UNPKG

@adonisjs/auth

Version:

Official authentication provider for Adonis framework

182 lines (181 loc) 5.73 kB
"use strict"; /* * @adonisjs/auth * * (c) Harminder Virk <virk@adonisjs.com> * * 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.BasicAuthGuard = void 0; const utils_1 = require("@poppinss/utils"); const helpers_1 = require("@poppinss/utils/build/helpers"); const Base_1 = require("../Base"); const AuthenticationException_1 = require("../../Exceptions/AuthenticationException"); /** * RegExp for basic auth credentials. * Copy/pasted from https://github.com/jshttp/basic-auth/blob/master/index.js * * credentials = auth-scheme 1*SP token68 * auth-scheme = "Basic" ; case insensitive * token68 = 1*( ALPHA / DIGIT / "-" / "." / "_" / "~" / "+" / "/" ) *"=" */ const CREDENTIALS_REGEXP = /^ *(?:[Bb][Aa][Ss][Ii][Cc]) +([A-Za-z0-9._~+/-]+=*) *$/; /** * RegExp for basic auth user/pass * Copy/pasted from https://github.com/jshttp/basic-auth/blob/master/index.js * * user-pass = userid ":" password * userid = *<TEXT excluding ":"> * password = *TEXT */ const USER_PASS_REGEXP = /^([^:]*):(.*)$/; /** * Basic auth guard enables user login using basic auth headers. */ class BasicAuthGuard extends Base_1.BaseGuard { constructor(name, config, emitter, provider, ctx) { super(name, config, provider); this.emitter = emitter; this.ctx = ctx; } /** * Returns data packet for the authenticate event. Arguments are * * - The mapping identifier * - Logged in user * - HTTP context */ getAuthenticateEventData(user) { return { name: this.name, ctx: this.ctx, user, }; } /** * Returns user credentials by parsing the HTTP "Authorization" header */ getCredentials() { /** * Ensure the "Authorization" header value exists */ const credentials = this.ctx.request.header('Authorization'); if (!credentials) { throw AuthenticationException_1.AuthenticationException.invalidBasicCredentials(this.name); } /** * Ensure credentials are in correct format */ const match = CREDENTIALS_REGEXP.exec(credentials); if (!match) { throw AuthenticationException_1.AuthenticationException.invalidBasicCredentials(this.name); } /** * Ensure credentials are base64 encoded */ const decoded = helpers_1.base64.decode(match[1], 'utf-8', true); if (!decoded) { throw AuthenticationException_1.AuthenticationException.invalidBasicCredentials(this.name); } /** * Ensure decoded credentials are in correct format */ const user = USER_PASS_REGEXP.exec(decoded); if (!user) { throw AuthenticationException_1.AuthenticationException.invalidBasicCredentials(this.name); } return { uid: user[1], password: user[2] }; } /** * Returns user for the uid and password. */ async getUser(uid, password) { try { return await this.verifyCredentials(uid, password); } catch { throw AuthenticationException_1.AuthenticationException.invalidBasicCredentials(this.name); } } /** * Implemented method to raise exception when someone calls this method * without selecting the guard explicitly */ async attempt() { return this.login(); } /** * Implemented method to raise exception when someone calls this method * without selecting the guard explicitly */ async loginViaId() { return this.login(); } /** * Implemented method to raise exception when someone calls this method * without selecting the guard explicitly */ async login() { throw new utils_1.Exception('There is no concept of login in basic auth', 500); } /** * Authenticates the current HTTP request by checking for the HTTP * "Authorization" header */ async authenticate() { if (this.authenticationAttempted) { return this.user; } this.authenticationAttempted = true; /** * Parse HTTP "Authorization" header to get credentials */ const credentials = this.getCredentials(); /** * Pull user from credentials */ const user = await this.getUser(credentials.uid, credentials.password); /** * Mark user a logged in */ this.markUserAsLoggedIn(user, true); /** * Emit event */ this.emitter.emit('adonis:basic:authenticate', this.getAuthenticateEventData(user)); return this.user; } /** * Same as [[authenticate]] but returns a boolean over raising exceptions */ async check() { try { await this.authenticate(); } catch (error) { this.ctx.logger.trace(error, 'Authentication failure'); } return this.isAuthenticated; } /** * Logout by clearing session and cookies */ async logout() { throw new utils_1.Exception('There is no concept of logout in basic auth', 500); } /** * Serialize toJSON for JSON.stringify */ toJSON() { return { isLoggedIn: this.isLoggedIn, isGuest: this.isGuest, authenticationAttempted: this.authenticationAttempted, isAuthenticated: this.isAuthenticated, user: this.user, }; } } exports.BasicAuthGuard = BasicAuthGuard;