balena-auth
Version:
Balena session authentication utilities
212 lines (209 loc) • 6.89 kB
JavaScript
"use strict";
/*
Copyright 2016-17 Balena
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.TokenType = void 0;
const tslib_1 = require("tslib");
/**
* @module auth
*/
const errors = require("balena-errors");
const balena_settings_storage_1 = require("balena-settings-storage");
const api_key_1 = require("./api-key");
const jwt_1 = require("./jwt");
var token_1 = require("./token");
Object.defineProperty(exports, "TokenType", { enumerable: true, get: function () { return token_1.TokenType; } });
class BalenaAuth {
constructor({ dataDirectory, tokenKey = 'token' } = {}) {
// Storage related methods
/**
* @member setKey
* @summary Set the key
* @function
* @public
*
* @param {String} key
* @returns {Promise<void>}
*
* @example
* auth.setKey('...').then(() => { ... });
*/
this.setKey = (key) => tslib_1.__awaiter(this, void 0, void 0, function* () {
this.token = this.createToken(key);
// Do not override the current key if the new one is invalid
return this.storage.set(this.tokenKey, key);
});
/**
* @member hasKey
* @summary Has a key
* @function
* @public
*
* @returns {Promise<Boolean>} has key
*
* @example
* auth.hasKey().then((hasKey) => { ... });
*/
this.hasKey = () => this.storage.has(this.tokenKey);
/**
* @member removeKey
* @summary Remove the key
* @function
* @public
*
* @description
* This promise is not rejected if there was no key at the time of removal.
*
* @returns {Promise}
*
* @example
* auth.removeKey();
*/
this.removeKey = () => {
this.token = undefined;
return this.storage.remove(this.tokenKey);
};
// Proxy promisified Token methods
/**
* @member getType
* @summary Gets the key type
* @function
* @public
*
* @returns {Promise<TokenType>}
*
* @example
* auth.getType().then((type) => { ... });
*/
this.getType = () => tslib_1.__awaiter(this, void 0, void 0, function* () {
const token = yield this.getToken();
return token.type;
});
/**
* @member getKey
* @summary Gets the key
* @function
* @public
*
* @returns {Promise<string>}
*
* @example
* auth.getKey().then((key) => { ... });
*/
this.getKey = () => tslib_1.__awaiter(this, void 0, void 0, function* () {
const token = yield this.getToken();
return token.key;
});
/**
* @member getAge
* @summary Gets the token age
* @function
* @public
*
* @returns {Promise<number | undefined>}
*
* @example
* auth.getAge().then((age) => { ... });
*/
this.getAge = () => tslib_1.__awaiter(this, void 0, void 0, function* () {
const token = yield this.getToken();
return token.getAge();
});
/**
* @member isExpired
* @summary Checks if token is expired
* @function
* @public
*
* @returns {Promise<boolean>}
*
* @example
* auth.isExpired().then((expired) => { ... });
*/
this.isExpired = () => tslib_1.__awaiter(this, void 0, void 0, function* () {
const token = yield this.getToken();
return token.isExpired();
});
/**
* @member isValid
* @summary Checks if token format is valid
* @function
* @public
*
* @returns {Promise<boolean>}
*
* @example
* auth.isValid().then((valid) => { ... });
*/
this.isValid = () => tslib_1.__awaiter(this, void 0, void 0, function* () {
const token = yield this.getToken();
return token.isValid();
});
/**
* @member get2FAStatus
* @summary Gets whether passing a 2FA challenge is pending, passed or not required.
* @function
* @public
*
* @returns {Promise<'not_required'|'pending'|'passed'>}
*
* @example
* auth.get2FAStatus().then((get2FAStatus) => { ... });
*/
this.get2FAStatus = () => tslib_1.__awaiter(this, void 0, void 0, function* () {
const token = yield this.getToken();
return token.get2FAStatus();
});
/**
* @member needs2FA
* @summary Checks whether passing 2FA is pending/needed
* @function
* @public
*
* @returns {Promise<boolean>}
*
* @example
* auth.needs2FA().then((needs2FA) => { ... });
*/
this.needs2FA = () => tslib_1.__awaiter(this, void 0, void 0, function* () {
const status = yield this.get2FAStatus();
return status === 'pending';
});
// Utility methods
this.createToken = (key) => {
const token = jwt_1.JWT.isValid(key) ? new jwt_1.JWT(key) : new api_key_1.APIKey(key);
if (!token.isValid()) {
throw new errors.BalenaMalformedToken(key);
}
if (token.isExpired()) {
throw new errors.BalenaExpiredToken(key);
}
return token;
};
this.getToken = () => tslib_1.__awaiter(this, void 0, void 0, function* () {
if (this.token) {
return this.token;
}
const key = yield this.storage.get(this.tokenKey);
if (typeof key !== 'string') {
throw new errors.BalenaMalformedToken(key);
}
this.token = this.createToken(key);
return this.token;
});
this.storage = (0, balena_settings_storage_1.getStorage)({ dataDirectory });
this.tokenKey = tokenKey;
}
}
exports.default = BalenaAuth;
//# sourceMappingURL=auth.js.map