UNPKG

@dallin.b.johnson/authentication-api-key

Version:

API Key authentication strategy for @feathers/authentication

94 lines (93 loc) 3.38 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const errors_1 = require("@feathersjs/errors"); const authentication_1 = require("@feathersjs/authentication"); class ApiKeyStrategy extends authentication_1.AuthenticationBaseStrategy { constructor() { super(); this.serviceBased = false; } verifyConfiguration() { this.serviceBased = ["service", "entity"].every(prop => prop in this.configuration); if (!this.serviceBased) { if (!("keys" in this.configuration)) { throw new Error(`A static keys is missing, when strategy '${this.name}', is not service based`); } } ["headerField"].forEach(prop => { if (prop in this.configuration) return; throw new Error(`'${prop}' is missing from configuration`); }); } get configuration() { const config = super.configuration || {}; return { errorMessage: "Invalid API key", entity: "api-key", ...config }; } async findEntity(apiKey, params) { const { errorMessage, entity } = this.configuration; try { const result = await this.entityService._find({ ...params, query: { [entity]: apiKey, $limit: 1 } }); if (result.total === 0) { throw new errors_1.NotAuthenticated(errorMessage); } return result.data[0]; } catch (error) { throw new errors_1.NotAuthenticated(errorMessage); } } async authenticate(authRequest, params) { const { keys, errorMessage, entity, revokedField, authorizedField, activeField, headerField } = this.configuration; const apiKey = authRequest[entity]; const result = { authentication: { strategy: this.name, [entity]: apiKey }, headers: { ...params.headers, [headerField]: apiKey }, apiKey: true, [entity]: {} }; if (!this.serviceBased) { if (!keys.includes(apiKey)) throw new errors_1.NotAuthenticated(errorMessage); return result; } const apiKeyData = await this.findEntity(apiKey, params); if (revokedField in apiKeyData) { if (apiKeyData[revokedField]) { throw new errors_1.NotAuthenticated("API Key has been revoked"); } } if (authorizedField in apiKeyData) { if (!apiKeyData[authorizedField]) { throw new errors_1.NotAuthenticated("API Key has not been authorized"); } } if (activeField in apiKeyData) { if (!apiKeyData[activeField]) { throw new errors_1.NotAuthenticated("API Key is not active"); } } return Object.assign(Object.assign({}, result), { [entity]: apiKeyData }); } async parse(req, res) { const { headerField, entity } = this.configuration; const apiKey = req.headers[headerField]; if (apiKey) { return { strategy: this.name, [entity]: apiKey }; } return null; } } exports.ApiKeyStrategy = ApiKeyStrategy;