@dallin.b.johnson/authentication-api-key
Version:
API Key authentication strategy for @feathers/authentication
94 lines (93 loc) • 3.38 kB
JavaScript
;
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;