UNPKG

@adonisjs/auth

Version:

Official authentication provider for Adonis framework

124 lines (123 loc) 4.1 kB
"use strict"; /* * @adonisjs/auth * * (c) AdonisJS * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ Object.defineProperty(exports, "__esModule", { value: true }); exports.OATClient = void 0; const luxon_1 = require("luxon"); const crypto_1 = require("crypto"); const utils_1 = require("@poppinss/utils"); const helpers_1 = require("@poppinss/utils/build/helpers"); const ProviderToken_1 = require("../../Tokens/ProviderToken"); /** * OAT client to login a user during tests using the * opaque tokens guard */ class OATClient { constructor(name, config, provider, tokenProvider) { this.name = name; this.config = config; this.provider = provider; this.tokenProvider = tokenProvider; /** * Length of the raw token. The hash length will vary */ this.tokenLength = 60; /** * Token type for the persistance store */ this.tokenType = this.config.tokenProvider.type || 'opaque_token'; } /** * Returns the provider user instance from the regular user details. Raises * exception when id is missing */ async getUserForLogin(user, identifierKey) { const providerUser = await this.provider.getUserFor(user); /** * Ensure id exists on the user */ const id = providerUser.getId(); if (!id) { throw new utils_1.Exception(`Cannot login user. Value of "${identifierKey}" is not defined`); } return providerUser; } /** * Converts value to a sha256 hash */ generateHash(token) { return (0, crypto_1.createHash)('sha256').update(token).digest('hex'); } /** * Converts expiry duration to an absolute date/time value */ getExpiresAtDate(expiresIn) { if (!expiresIn) { return; } const milliseconds = typeof expiresIn === 'string' ? helpers_1.string.toMs(expiresIn) : expiresIn; return luxon_1.DateTime.local().plus({ milliseconds }); } /** * Generates a new token + hash for the persistance */ generateTokenForPersistance(expiresIn) { const token = helpers_1.string.generateRandom(this.tokenLength); return { token, hash: this.generateHash(token), expiresAt: this.getExpiresAtDate(expiresIn), }; } /** * Returns the request data to mark user as logged in */ async login(user, options) { /** * Normalize options with defaults */ const { expiresIn, name, ...meta } = Object.assign({ name: 'Opaque Access Token', }, options); /** * Since the login method is not exposed to the end user, we cannot expect * them to instantiate and pass an instance of provider user, so we * create one manually. */ const providerUser = await this.getUserForLogin(user, this.config.provider.identifierKey); /** * "getUserForLogin" raises exception when id is missing, so we can * safely assume it is defined */ const id = providerUser.getId(); const token = this.generateTokenForPersistance(expiresIn); /** * Persist token to the database. Make sure that we are always * passing the hash to the storage driver */ const providerToken = new ProviderToken_1.ProviderToken(name, token.hash, id, this.tokenType); providerToken.expiresAt = token.expiresAt; providerToken.meta = meta; this.tokenId = await this.tokenProvider.write(providerToken); return { headers: { Authorization: `Bearer ${helpers_1.base64.urlEncode(this.tokenId)}.${token.token}`, }, }; } /** * Logout user */ async logout() { if (this.tokenId) { await this.tokenProvider.destroy(this.tokenId, this.tokenType); } } } exports.OATClient = OATClient;