UNPKG

@titanium/authentication-mock

Version:

⭐ Axway Amplify module for mocking OAuth Authentication with Appcelerator Titanium SDK Framework

168 lines (143 loc) 4.73 kB
const _ = require('lodash'); const jwt = require('@titanium/jwt'); const moment = require('moment'); const path = require('path'); const fs = require('fs'); // TIBUG: __dirname will randomly be undefined // console.debug(`🦠 __dirname: ${JSON.stringify(__dirname, null, 2)}`); const kids = [ 'a5f23fbc289dac0e9eada1aa0ac2e27f' ]; let mock_users_path = './mock-users.json'; // TIBUG: Titanium can't handle relative paths when loading files so must convert to absolute path if (typeof Ti !== 'undefined') { mock_users_path = path.join(Ti.Filesystem.resourcesDirectory, `./${__dirname}`, mock_users_path); } export class MockAuthentication { constructor({ users, audience = 'audience', client_id = 'client_id', device, issuer = 'issuer', subject = 'subject', access_token_expires_in = 300, // 5 minutes refresh_token_expires_in = 5259492, // 2 months scopes = [ 'scope1' ], kid = kids[0], } = {}) { this.users = users; this.audience = audience; this.client_id = client_id; this.device = device; this.issuer = issuer; this.scopes = scopes; this.subject = subject; this.access_token_expires_in = access_token_expires_in; this.refresh_token_expires_in = refresh_token_expires_in; this.kid = kid; if (!this.users) { try { this.users = JSON.parse(fs.readFileSync(mock_users_path, 'utf8')); } catch (error) { console.error(error); this.users = []; } } } async getPublicKey({ kid } = {}) { console.debug(`📌 you are here → MockAuthentication.getPublicKey({kid:${kid}})`); if (!kid) { return this.getPublicKey({ kid: this.kid }); } let public_key_path = `./keys/public/${kid}.pub`; // TIBUG: Titanium can't handle relative paths when loading files so must convert to absolute path if (typeof Ti !== 'undefined') { public_key_path = path.join(Ti.Filesystem.resourcesDirectory, `./${__dirname}`, public_key_path); } const public_key = fs.readFileSync(public_key_path, 'utf8'); if (! this.public_key && (kid === this.kid)) { this.public_key = public_key; } return public_key; } async authenticate({ username, password, options: { audience = this.audience, client_id = this.client_id, device = this.device || require('crypto').createHash('md5').update(username).digest('hex'), issuer = this.issuer, scopes = this.scopes, subject = this.subject, access_token_expires_in = this.access_token_expires_in, refresh_token_expires_in = this.refresh_token_expires_in, kid = this.kid, } = {}, } = {}) { const response = { authenticated: false, claims: [], }; if (!username || !password || username !== password) { response.error = 'authentication failed'; return response; } const user = _.find(this.users, { username }); if (!user) { response.error = 'user not found'; return response; } const getPrivateKey = async ({ kid } = {}) => { let private_key_path = `./keys/private/${kid}.key`; // TIBUG: Titanium can't handle relative paths when loading files so must convert to absolute path if (typeof Ti !== 'undefined') { private_key_path = path.join(Ti.Filesystem.resourcesDirectory, `./${__dirname}`, private_key_path); } const private_key = fs.readFileSync(private_key_path, 'utf8'); return private_key; }; const private_key = await getPrivateKey({ kid }); response.access_token = jwt.sign( { token: user.token, name: user.formatted_name, given_name: user.first_name, family_name: user.last_name, picture: user.picture, updated_at: user.entity_updated_at, client_id: client_id, username: username, userid: user.id, email: user.email, email_verified: user.email_verified, job_title: user.job_title, zoneinfo: user.timezone, phone_number: user.phone, phone_number_verified: user.phone_verified, auth_time: moment(), scope: scopes.join(' '), azp: device, kid, }, private_key, { algorithm: 'RS256', issuer: issuer, subject: subject, audience: audience, expiresIn: access_token_expires_in, }, ); response.user = { username: username, first_name: user.first_name, last_name: user.last_name, formatted_name: user.formatted_name, email: user.email, }; response.authenticated = true; console.debug(`🦠 MockAuthentication response: ${JSON.stringify(response, null, 2)}`); return response; } } module.exports = MockAuthentication;