Timo Hocker
31f739d4b8
All checks were successful
continuous-integration/drone/push Build is passing
105 lines
2.9 KiB
TypeScript
105 lines
2.9 KiB
TypeScript
/*
|
|
* Copyright (C) Sapphirecode - All Rights Reserved
|
|
* This file is part of Auth-Server-Helper which is released under MIT.
|
|
* See file 'LICENSE' for full license details.
|
|
* Created by Timo Hocker <timo@scode.ovh>, December 2020
|
|
*/
|
|
|
|
import { debug } from './debug';
|
|
import { redis_blacklist_store } from './RedisData/RedisBlacklistStore';
|
|
|
|
const logger = debug ('blacklist');
|
|
|
|
interface Signature {
|
|
hash: string;
|
|
iat: number;
|
|
}
|
|
|
|
class Blacklist {
|
|
private _signatures: Signature[];
|
|
|
|
public constructor () {
|
|
this._signatures = [];
|
|
}
|
|
|
|
public async clear (
|
|
before: number = Number.POSITIVE_INFINITY
|
|
): Promise<void> {
|
|
logger.extend ('clear') ('clearing blacklist');
|
|
for (let i = this._signatures.length - 1; i >= 0; i--) {
|
|
if (this._signatures[i].iat < before) {
|
|
// eslint-disable-next-line no-await-in-loop
|
|
await this.remove_signature (i);
|
|
}
|
|
}
|
|
}
|
|
|
|
public async add_signature (hash: string): Promise<void> {
|
|
logger.extend ('add_signature') ('blacklisting signature %s', hash);
|
|
this._signatures.push ({ iat: Date.now (), hash });
|
|
await redis_blacklist_store.add (hash);
|
|
}
|
|
|
|
public async remove_signature (signature: number | string): Promise<void> {
|
|
const log = logger.extend ('remove_signature');
|
|
log ('removing signature from blacklist %s', signature);
|
|
let key = '';
|
|
if (typeof signature === 'string') {
|
|
log ('received string, searching through signatures');
|
|
key = signature;
|
|
for (let i = this._signatures.length - 1; i >= 0; i--) {
|
|
if (this._signatures[i].hash === signature)
|
|
this._signatures.splice (i, 1);
|
|
}
|
|
}
|
|
else {
|
|
log ('received index, removing at index');
|
|
key = this._signatures[signature].hash;
|
|
this._signatures.splice (signature, 1);
|
|
}
|
|
await redis_blacklist_store.remove (key);
|
|
}
|
|
|
|
public async is_valid (hash: string): Promise<boolean> {
|
|
const log = logger.extend ('is_valid');
|
|
log ('checking signature for blacklist entry %s', hash);
|
|
for (const sig of this._signatures) {
|
|
if (sig.hash === hash) {
|
|
log ('found matching blacklist entry');
|
|
return false;
|
|
}
|
|
}
|
|
|
|
log ('signature is not blacklisted locally, checking redis');
|
|
if (await redis_blacklist_store.get (hash)) {
|
|
log ('signature is blacklisted in redis');
|
|
return false;
|
|
}
|
|
|
|
log ('signature is not blacklisted');
|
|
return true;
|
|
}
|
|
|
|
public export_blacklist (): Signature[] {
|
|
logger.extend ('export_blacklist') ('exporting blacklist');
|
|
return this._signatures;
|
|
}
|
|
|
|
public import_blacklist (data: Signature[]): void {
|
|
logger.extend ('import_blacklist') (
|
|
'importing %d blacklist entries',
|
|
data.length
|
|
);
|
|
this._signatures.push (...data);
|
|
}
|
|
|
|
public sync_redis (url: string): void {
|
|
redis_blacklist_store.connect (url);
|
|
}
|
|
}
|
|
|
|
const bl = (new Blacklist);
|
|
|
|
export { Blacklist };
|
|
export default bl;
|