add security api class

merge-requests/1/merge
Matthew 2019-11-16 19:24:32 -05:00
parent ed9d095e78
commit e42761dcda
No known key found for this signature in database
GPG Key ID: 766BE43AE75F7559
1 changed files with 58 additions and 0 deletions

58
src/api/Security.ts Normal file
View File

@ -0,0 +1,58 @@
import crypto from 'crypto';
import { Request } from 'express';
import { Client } from '..';
export default class Security {
public client: Client;
public keyPair: { publicKey: string, privateKey: string };
constructor(client: Client) {
this.client = client;
this.keyPair = client.config.keyPair;
}
/**
* Creates a new Bearer token.
* @param _id The Mongoose Document property labeled ._id
*/
public async createBearer(_id: string): Promise<string> {
const account = await this.client.db.Account.findOne({ _id });
if (!account) throw new Error(`Account [${_id}] cannot be found.`);
const bearer = crypto.randomBytes(12);
const sign = crypto.createSign('sha3-224');
sign.update(bearer);
sign.end();
const signature = sign.sign(this.keyPair.privateKey, 'hex');
await account.updateOne({ bearerSignature: signature });
return bearer.toString('base64');
}
public async checkBearer(_id: string, bearer: string): Promise<boolean> {
const account = await this.client.db.Account.findOne({ _id });
if (!account) return false;
if (!account.bearerSignature) return false;
const verify = crypto.createVerify('sha3-224');
verify.update(bearer);
verify.end();
try {
return verify.verify(this.keyPair.publicKey, account.bearerSignature, 'base64');
} catch {
return false;
}
}
public extractBearer(req: Request): string {
const url = new URL(req.url);
if (req.headers.authorization && req.headers.authorization.split(' ')[0] === 'Bearer') {
return req.headers.authorization.split(' ')[1];
}
if (req.query && req.query.token) {
return req.query.token;
}
if (url.password) {
return url.password;
}
return 'null';
}
}