UNPKG

@simulacrum/auth0-simulator

Version:

Run local instance of Auth0 API for local development and integration testing

145 lines 6.37 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.getBaseAccessToken = exports.getIdToken = exports.createTokens = void 0; const assert_ts_1 = require("assert-ts"); const base64_url_1 = require("base64-url"); const date_ts_1 = require("../auth/date.js"); const jwt_ts_1 = require("../auth/jwt.js"); const rules_runner_ts_1 = require("../rules/rules-runner.js"); const utils_ts_1 = require("./utils.js"); const refresh_token_ts_1 = require("../auth/refresh-token.js"); const createTokens = (_a) => __awaiter(void 0, [_a], void 0, function* ({ body, iss, clientID, audience, rulesDirectory, scope: scopeConfig, simulationStore, }) { let { grant_type } = body; let scope = (0, utils_ts_1.deriveScope)({ scopeConfig, clientID, audience }); let accessToken = (0, exports.getBaseAccessToken)({ iss, grant_type, scope, audience }); let user; let nonce; if (grant_type === "client_credentials") { return { access_token: (0, jwt_ts_1.createJsonWebToken)(accessToken) }; } // TODO: check refresh_token expiry date else if (grant_type === "refresh_token") { let { refresh_token: refreshTokenValue } = body; let refreshToken = JSON.parse((0, base64_url_1.decode)(refreshTokenValue)); let findUser = (0, utils_ts_1.createPersonQuery)(simulationStore); user = findUser((person) => person.id === refreshToken.user.id); nonce = refreshToken.nonce; (0, assert_ts_1.assert)(!!nonce, `400::No nonce in request`); } else { let result = verifyUserExistsInStore({ simulationStore, body, grant_type, }); user = result.user; nonce = result.nonce; } (0, assert_ts_1.assert)(!!user, "500::No user found"); let { idTokenData, userData } = (0, exports.getIdToken)({ body, iss, user, clientID, nonce, }); let context = { clientID, accessToken: { scope, sub: idTokenData.sub }, idToken: idTokenData, }; let rulesRunner = (0, rules_runner_ts_1.createRulesRunner)(rulesDirectory); // the rules mutate the values yield rulesRunner(userData, context); return { access_token: (0, jwt_ts_1.createJsonWebToken)(Object.assign(Object.assign(Object.assign({}, accessToken), context.accessToken), (scope.split(" ").includes("email") ? { email: user.email } : {}))), id_token: (0, jwt_ts_1.createJsonWebToken)(Object.assign(Object.assign({}, userData), context.idToken)), refresh_token: (0, refresh_token_ts_1.issueRefreshToken)(scope, grant_type) ? (0, refresh_token_ts_1.createRefreshToken)({ exp: idTokenData.exp, rotations: 0, scope, user, nonce, }) : undefined, }; }); exports.createTokens = createTokens; const getIdToken = ({ body, iss, user, clientID, nonce, }) => { var _a, _b, _c, _d; let userData = { name: (_a = body === null || body === void 0 ? void 0 : body.name) !== null && _a !== void 0 ? _a : user.name, email: (_b = body === null || body === void 0 ? void 0 : body.email) !== null && _b !== void 0 ? _b : user.email, email_verified: true, user_id: (_c = body === null || body === void 0 ? void 0 : body.id) !== null && _c !== void 0 ? _c : user.id, nickname: body === null || body === void 0 ? void 0 : body.nickname, picture: (_d = body === null || body === void 0 ? void 0 : body.picture) !== null && _d !== void 0 ? _d : user.picture, identities: body === null || body === void 0 ? void 0 : body.identities, }; (0, assert_ts_1.assert)(!!user.email, "500::User in store requires an email"); let idTokenData = { alg: "RS256", typ: "JWT", iss, exp: (0, date_ts_1.expiresAt)(), iat: (0, date_ts_1.epochTime)(), email: user.email, aud: clientID, sub: user.id, }; if (typeof nonce !== "undefined") { idTokenData.nonce = nonce; } return { userData, idTokenData }; }; exports.getIdToken = getIdToken; const getBaseAccessToken = ({ iss, grant_type, scope, audience, }) => ({ iss, exp: (0, date_ts_1.expiresAt)(), iat: (0, date_ts_1.epochTime)(), aud: audience, gty: grant_type, scope, }); exports.getBaseAccessToken = getBaseAccessToken; const verifyUserExistsInStore = ({ simulationStore, body, grant_type, }) => { let { code } = body; let personQuery = (0, utils_ts_1.createPersonQuery)(simulationStore); let nonce; let username; let password; if (grant_type === "password") { username = body.username; password = body.password; } else { // specifically grant_type === 'authorization_code' // but naively using it to handle other cases at the moment (0, assert_ts_1.assert)(typeof code !== "undefined", "400::no code in /oauth/token"); [nonce, username] = (0, base64_url_1.decode)(code).split(":"); } (0, assert_ts_1.assert)(!!username, `400::no nonce in store for ${code}`); let user = personQuery((person) => { (0, assert_ts_1.assert)(!!person.email, `500::no email defined on person scenario`); let valid = person.email.toLowerCase() === username.toLowerCase(); if (typeof password === "undefined") { return valid; } else { return valid && password === person.password; } }); (0, assert_ts_1.assert)(!!user, "401::Unauthorized"); return { user, nonce }; }; //# sourceMappingURL=oauth-handlers.js.map