Skip to content

enhancement: new fake backend with roles and multiple accounts #4

@thawkins

Description

@thawkins

I added the ability to specify multiple accounts to the fake back end. and added a role element

This was mainly so i could experiment with dynamic navigation rendering. It may be useful for others.

Its my first real javascript hack, mainly php and java/kotlin up to now. so be gentle. :-)

The code takes care of generating and verifying multiple unique fake jwt tokens.

The core of the get users code could do with moving to a separate function so that it can be used to authenticate more fake be urls.

===== fake-backend.js =======

export function configureFakeBackend() {
    let users = [
        {id: 1, username: 'test', password: 'test', firstName: 'Test', lastName: 'User', 'role': ["user"]},
        {id: 2, username: 'admin', password: 'admin', firstName: 'Admin', lastName: 'User', 'role': ["admin", "user"]}
    ];
    let realFetch = window.fetch;
    window.fetch = function (url, opts) {
        return new Promise((resolve, reject) => {
            // wrap in timeout to simulate server api call
            setTimeout(() => {

                // authenticate
                if (url.endsWith('/users/authenticate') && opts.method === 'POST') {
                    // get parameters from post request
                    let params = JSON.parse(opts.body);

                    // find if any user matches login credentials
                    let filteredUsers = users.filter(user => {
                        return user.username === params.username && user.password === params.password;
                    });

                    if (filteredUsers.length) {
                        // if login details are valid return user details and fake jwt token
                        let user = filteredUsers[0];
                        let responseJson = {
                            id: user.id,
                            username: user.username,
                            firstName: user.firstName,
                            lastName: user.lastName,
                            role: user.role,
                            token: 'fake-jwt-token-' + user.id
                        };
                        resolve({ok: true, text: () => Promise.resolve(JSON.stringify(responseJson))});
                    } else {
                        // else return error
                        reject('Username or password is incorrect');
                    }

                    return;
                }

                // get users
                if (url.endsWith('/users') && opts.method === 'GET') {
                    // check for fake auth token in header and return users if valid, this security is implemented server side in a real application
                    if (opts.headers) {
                        let userid = Number(opts.headers.Authorization.replace(/^\D+/g, ''));   // replace all leading non-digits with nothing
                        let found = false;
                        // Horribly inefficient linear search but allows the ids to be non sequential and sparse. 
                        for (let i = 0; i < users.length; i++) {
                            if (users[i].id === userid) {
                                found = true;
                                break;
                            }
                        }
                        if (found && opts.headers.Authorization === ('Bearer fake-jwt-token-' + userid)) {
                            resolve({ok: true, text: () => Promise.resolve(JSON.stringify(users))});
                            return;
                        }
                    } // return 401 not authorised if token is null or invalid
                    reject('Unauthorised');
                    return;
                }
                // pass through any requests not handled above
                realFetch(url, opts).then(response => resolve(response));

            }, 500);
        });
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions