@adonisjs/auth
Version:
Official authentication provider for Adonis framework
127 lines (126 loc) • 4.19 kB
JavaScript
"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.TokenDatabaseProvider = void 0;
const luxon_1 = require("luxon");
const helpers_1 = require("@poppinss/utils/build/helpers");
const ProviderToken_1 = require("../../Tokens/ProviderToken");
/**
* Database backend tokens provider
*/
class TokenDatabaseProvider {
constructor(config, db) {
this.config = config;
this.db = db;
/**
* The foreign key column
*/
this.foreignKey = this.config.foreignKey || 'user_id';
}
/**
* Returns the query client for database queries
*/
getQueryClient() {
if (!this.connection) {
return this.db.connection(this.config.connection);
}
return typeof this.connection === 'string'
? this.db.connection(this.connection)
: this.connection;
}
/**
* Returns the builder query for a given token + type
*/
getLookupQuery(tokenId, tokenType) {
return this.getQueryClient()
.from(this.config.table)
.where('id', tokenId)
.where('type', tokenType);
}
/**
* Define custom connection
*/
setConnection(connection) {
this.connection = connection;
return this;
}
/**
* Reads the token using the lookup token id
*/
async read(tokenId, tokenHash, tokenType) {
const client = this.getQueryClient();
/**
* Find token using id
*/
const tokenRow = await this.getLookupQuery(tokenId, tokenType).first();
if (!tokenRow || !tokenRow.token) {
return null;
}
/**
* Ensure hash of the user provided value is same as the one inside
* the database
*/
if (!(0, helpers_1.safeEqual)(tokenRow.token, tokenHash)) {
return null;
}
const { name, [this.foreignKey]: userId, token: value, expires_at: expiresAt, type, ...meta } = tokenRow;
let normalizedExpiryDate;
/**
* Parse dialect date to an instance of Luxon
*/
if (expiresAt instanceof Date) {
normalizedExpiryDate = luxon_1.DateTime.fromJSDate(expiresAt);
}
else if (expiresAt && typeof expiresAt === 'string') {
normalizedExpiryDate = luxon_1.DateTime.fromFormat(expiresAt, client.dialect.dateTimeFormat);
}
else if (expiresAt && typeof expiresAt === 'number') {
normalizedExpiryDate = luxon_1.DateTime.fromMillis(expiresAt);
}
/**
* Ensure token isn't expired
*/
if (normalizedExpiryDate &&
normalizedExpiryDate.diff(luxon_1.DateTime.local(), 'milliseconds').milliseconds <= 0) {
return null;
}
const token = new ProviderToken_1.ProviderToken(name, value, userId, type);
token.expiresAt = expiresAt;
token.meta = meta;
return token;
}
/**
* Saves the token and returns the persisted token lookup id.
*/
async write(token) {
const client = this.getQueryClient();
/**
* Payload to save to the database
*/
const payload = {
[this.foreignKey]: token.userId,
name: token.name,
token: token.tokenHash,
type: token.type,
expires_at: token.expiresAt ? token.expiresAt.toFormat(client.dialect.dateTimeFormat) : null,
created_at: luxon_1.DateTime.local().toFormat(client.dialect.dateTimeFormat),
...token.meta,
};
const [row] = await client.table(this.config.table).insert(payload).returning('id');
return String(typeof row === 'number' ? row : row.id);
}
/**
* Removes a given token
*/
async destroy(tokenId, tokenType) {
await this.getLookupQuery(tokenId, tokenType).delete();
}
}
exports.TokenDatabaseProvider = TokenDatabaseProvider;