foocorp / hacienda

The Hacienda must be built
GNU Affero General Public License v3.0
224 stars 7 forks source link

App passwords discussion #36

Open mattl opened 5 days ago

mattl commented 5 days ago

13 got off-topic.

@foocorp/beta-testers please keep things on-topic.

App passwords: Please check out this prototype. https://bored.city/demo.html

fam007e commented 4 days ago

Does it look too simple to implement from me:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>App Password Demo</title>
    <link rel="icon" href="/favicon.ico?v=1727201545">
    <style>
        body {
            font-family: Arial, sans-serif;
            padding: 20px;
            background-color: #f4f4f4;
        }
        fieldset {
            background-color: white;
            border-radius: 8px;
            padding: 20px;
        }
        input[type="text"], input[type="url"], textarea {
            width: 100%;
            padding: 8px;
            margin: 8px 0;
            border-radius: 4px;
            border: 1px solid #ccc;
        }
        .hidden {
            display: none;
        }
        .strength-indicator {
            font-size: 14px;
            color: green;
        }
    </style>
</head>
<body>
    <main>
        <h1>App Password Generator</h1>
        <fieldset>
            <legend>Select Authentication Method</legend>
            <p>
                <label>
                    <input type="radio" class="radio" checked="checked" name="auth" id="librefm"> Libre.fm Username
                </label>
            </p>
            <p>
                <label>
                    <input type="radio" class="radio" name="auth" id="indieauth"> IndieAuth
                </label>
            </p>

            <p id="client">
                <label for="clientID">Client Name:</label>
                <input id="clientID" type="text" value="Rhythmbox for Linux" aria-label="Client Name" />
            </p>

            <hr />

            <!-- IndieAuth URL Input -->
            <p id="url" class="hidden">
                <label for="url_url">IndieAuth URL:</label>
                <input id="url_url" type="url" value="https://example.com" disabled />
                <input type="button" value="Generate" onclick="generateIndie()" />
            </p>

            <!-- Libre.fm Username Input -->
            <p id="rowUserName">
                <label for="txtUserName">Libre.fm Username:</label>
                <input type="text" name="username" id="txtUserName" value="example-user" aria-label="Libre.fm Username">
                <input type="button" value="Generate" onclick="generateApp()" />
            </p>

            <hr />

            <h2>Generated Credentials (Do not use)</h2>
            <textarea style="font-family: monospace; font-size: 16px;" rows="4" id="output" readonly></textarea>
        </fieldset>
    </main>

    <script>
        // Toggle between Libre.fm and IndieAuth views
        document.getElementById("indieauth").onclick = function() {
            document.getElementById("rowUserName").style.display = "none";
            document.getElementById("url").style.display = "block";
        }

        document.getElementById("librefm").onclick = function() {
            document.getElementById("rowUserName").style.display = "block";
            document.getElementById("url").style.display = "none";
        }

        // Helper to get the client ID
        function getClient() {
            let clientID = document.getElementById("clientID").value.toLowerCase();
            clientID = clientID.replace(/\s+/g, "-");
            return clientID;
        }

        // Password generator function
        function generatePassword(length) {
            const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
            let password = "";
            for (let i = 0; i < length; i++) {
                password += charset.charAt(Math.floor(Math.random() * charset.length));
            }
            return password;
        }

        // Generate credentials for Libre.fm
        function generateApp() {
            const username = document.getElementById("txtUserName").value;
            const client = getClient();
            const password = generatePassword(14);
            const generatedUsername = `${username}-${client}-${generatePassword(8)}`;

            document.getElementById("output").value = `Username: ${generatedUsername}\nPassword: ${password}`;
        }

        // Generate credentials for IndieAuth
        function generateIndie() {
            const client = getClient();
            const username = generatePassword(14);
            const password = generatePassword(14);
            const generatedUsername = `librefm-${client}-${username}`;

            document.getElementById("output").value = `Username: ${generatedUsername}\nPassword: ${password}`;
        }
    </script>
</body>
</html>

Key Enhancements:

1. Improved Styling:

2. Functionality:

3. Accessibility:

4. Password Generation:

mattl commented 4 days ago

To be clear this is a mockup. We’re going to have lots of them. They’re intentionally simple and without CSS.

millette commented 4 days ago

Replying to https://github.com/foocorp/hacienda/issues/13#issuecomment-2389428609

Not exactly a quote, but here's the relevant RFC: https://datatracker.ietf.org/doc/html/rfc1035#section-2.3.4.

stinerman commented 4 days ago

Re: https://bored.city/demo.html

It appears that you're replacing spaces in the client name with dashes. This is not true of the username. For example:

image

This might be a problem, but only a problem if you allow spaces in the username.

mattl commented 4 days ago

Yeah, we don't allow that. I think we'll be okay.