This commit is contained in:
@ -74,7 +74,7 @@ class Authority {
|
||||
|
||||
log ('parsing token %s %s', result.type, result.id);
|
||||
|
||||
if (!blacklist.is_valid (data.id)) {
|
||||
if (!(await blacklist.is_valid (data.id))) {
|
||||
log ('token is blacklisted');
|
||||
result.error = 'blacklisted';
|
||||
return result;
|
||||
|
@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
import { debug } from './debug';
|
||||
import { redis_blacklist_store } from './RedisData/RedisBlacklistStore';
|
||||
|
||||
const logger = debug ('blacklist');
|
||||
|
||||
@ -21,24 +22,31 @@ class Blacklist {
|
||||
this._signatures = [];
|
||||
}
|
||||
|
||||
public clear (before: number = Number.POSITIVE_INFINITY): void {
|
||||
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)
|
||||
this.remove_signature (i);
|
||||
if (this._signatures[i].iat < before) {
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
await this.remove_signature (i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public add_signature (hash: string): void {
|
||||
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 remove_signature (signature: number | string): void {
|
||||
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);
|
||||
@ -46,11 +54,13 @@ class Blacklist {
|
||||
}
|
||||
else {
|
||||
log ('received index, removing at index');
|
||||
key = this._signatures[signature].hash;
|
||||
this._signatures.splice (signature, 1);
|
||||
}
|
||||
await redis_blacklist_store.remove (key);
|
||||
}
|
||||
|
||||
public is_valid (hash: string): boolean {
|
||||
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) {
|
||||
@ -60,6 +70,12 @@ class Blacklist {
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
@ -76,6 +92,10 @@ class Blacklist {
|
||||
);
|
||||
this._signatures.push (...data);
|
||||
}
|
||||
|
||||
public sync_redis (url: string): void {
|
||||
redis_blacklist_store.connect (url);
|
||||
}
|
||||
}
|
||||
|
||||
const bl = (new Blacklist);
|
||||
|
@ -209,8 +209,10 @@ class GatewayClass {
|
||||
|
||||
log ('found %d tokens: %O', tokens.length, tokens);
|
||||
|
||||
for (const token of tokens)
|
||||
blacklist.add_signature (token.id);
|
||||
for (const token of tokens) {
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
await blacklist.add_signature (token.id);
|
||||
}
|
||||
|
||||
log ('complete');
|
||||
}
|
||||
|
@ -9,7 +9,6 @@ import { generate_keypair, random_hex } from '@sapphirecode/crypto-helper';
|
||||
import { to_b58 } from '@sapphirecode/encoding-helper';
|
||||
import { debug } from './debug';
|
||||
import { KeyStoreData, KeyStoreExport } from './Key';
|
||||
import { redis } from './Redis';
|
||||
import { redis_key_store } from './RedisData/RedisKeyStore';
|
||||
|
||||
const logger = debug ('keystore');
|
||||
@ -20,7 +19,6 @@ class KeyStore {
|
||||
private _keys: KeyStoreData = {};
|
||||
private _interval: NodeJS.Timeout;
|
||||
private _instance: string;
|
||||
private _sync_redis = false;
|
||||
|
||||
public get instance_id (): string {
|
||||
return this._instance;
|
||||
@ -58,8 +56,7 @@ class KeyStore {
|
||||
valid_until: time + (valid_for * 1000)
|
||||
}
|
||||
};
|
||||
if (this._sync_redis)
|
||||
await redis_key_store.set ({ ...result.public_key, index });
|
||||
await redis_key_store.set ({ ...result.public_key, index });
|
||||
this._keys[index] = result;
|
||||
}
|
||||
|
||||
@ -135,11 +132,11 @@ class KeyStore {
|
||||
|
||||
let key = null;
|
||||
|
||||
if (typeof this._keys[index] === 'undefined') {
|
||||
if (this._sync_redis)
|
||||
key = await redis_key_store.get (index);
|
||||
}
|
||||
else { key = this._keys[index].public_key; }
|
||||
if (typeof this._keys[index] === 'undefined')
|
||||
key = await redis_key_store.get (index);
|
||||
|
||||
else
|
||||
key = this._keys[index].public_key;
|
||||
|
||||
if (key === null)
|
||||
throw new Error ('key could not be found');
|
||||
@ -182,13 +179,11 @@ class KeyStore {
|
||||
logger.extend ('reset_instance') ('resetting keystore');
|
||||
this._instance = to_b58 (random_hex (16), 'hex');
|
||||
this._keys = {};
|
||||
this._sync_redis = false;
|
||||
redis.disconnect ();
|
||||
redis_key_store.disconnect ();
|
||||
}
|
||||
|
||||
public sync_redis (url: string): void {
|
||||
redis.connect (url);
|
||||
this._sync_redis = true;
|
||||
redis_key_store.connect (url);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -51,16 +51,14 @@ export class Redis {
|
||||
log ('done');
|
||||
}
|
||||
|
||||
public get redis (): IORedis {
|
||||
protected get redis (): IORedis {
|
||||
if (this._redis === null)
|
||||
throw new Error ('redis is not connected');
|
||||
|
||||
return this._redis;
|
||||
}
|
||||
|
||||
public get is_active (): boolean {
|
||||
protected get is_active (): boolean {
|
||||
return this._redis !== null;
|
||||
}
|
||||
}
|
||||
|
||||
export const redis = (new Redis);
|
||||
|
@ -6,31 +6,44 @@
|
||||
*/
|
||||
|
||||
import { debug } from '../debug';
|
||||
import { redis } from '../Redis';
|
||||
import { Redis } from '../Redis';
|
||||
|
||||
const logger = debug ('RedisBlacklistStore');
|
||||
|
||||
export class RedisBlacklistStore {
|
||||
export class RedisBlacklistStore extends Redis {
|
||||
public async add (key: string): Promise<void> {
|
||||
const log = logger.extend ('set');
|
||||
log ('trying to add key %s to redis blacklist', key);
|
||||
if (!redis.is_active) {
|
||||
if (!this.is_active) {
|
||||
log ('redis is inactive, skipping');
|
||||
return;
|
||||
}
|
||||
await redis.redis.sadd ('blacklist', key);
|
||||
await this.redis.sadd ('blacklist', key);
|
||||
log ('saved key');
|
||||
}
|
||||
|
||||
public async remove (key: string): Promise<void> {
|
||||
const log = logger.extend ('remove');
|
||||
log ('removing key %s from redis', key);
|
||||
if (!this.is_active) {
|
||||
log ('redis is inactive, skipping');
|
||||
return;
|
||||
}
|
||||
await this.redis.srem ('blacklist', key);
|
||||
log ('removed key');
|
||||
}
|
||||
|
||||
public async get (key: string): Promise<boolean> {
|
||||
const log = logger.extend ('get');
|
||||
log ('trying to find key %s in redis blacklist', key);
|
||||
if (!redis.is_active) {
|
||||
if (!this.is_active) {
|
||||
log ('redis is inactive, skipping');
|
||||
return false;
|
||||
}
|
||||
const res = await redis.redis.sismember ('blacklist', key) === 1;
|
||||
const res = await this.redis.sismember ('blacklist', key) === 1;
|
||||
log ('found key %s', res);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
export const redis_blacklist_store = new RedisBlacklistStore;
|
||||
|
@ -7,15 +7,15 @@
|
||||
|
||||
import { debug } from '../debug';
|
||||
import { LabelledKey } from '../Key';
|
||||
import { redis } from '../Redis';
|
||||
import { Redis } from '../Redis';
|
||||
|
||||
const logger = debug ('RedisKeyStore');
|
||||
|
||||
export class RedisKeyStore {
|
||||
export class RedisKeyStore extends Redis {
|
||||
public async set (value: LabelledKey): Promise<void> {
|
||||
const log = logger.extend ('set');
|
||||
log ('trying to set key %s to redis', value.index);
|
||||
if (!redis.is_active) {
|
||||
if (!this.is_active) {
|
||||
log ('redis is inactive, skipping');
|
||||
return;
|
||||
}
|
||||
@ -24,7 +24,7 @@ export class RedisKeyStore {
|
||||
.getTime ()) / 1000
|
||||
);
|
||||
log ('key is valid for %d seconds', valid_for);
|
||||
await redis.redis.setex (
|
||||
await this.redis.setex (
|
||||
`keystore_${value.index}`,
|
||||
valid_for,
|
||||
JSON.stringify (value)
|
||||
@ -35,11 +35,11 @@ export class RedisKeyStore {
|
||||
public async get (index: string): Promise<LabelledKey | null> {
|
||||
const log = logger.extend ('get');
|
||||
log ('trying to get key %s from redis', index);
|
||||
if (!redis.is_active) {
|
||||
if (!this.is_active) {
|
||||
log ('redis is inactive, skipping');
|
||||
return null;
|
||||
}
|
||||
const res = await redis.redis.get (`keystore_${index}`);
|
||||
const res = await this.redis.get (`keystore_${index}`);
|
||||
if (res === null) {
|
||||
log ('key not found in redis');
|
||||
return null;
|
||||
|
Reference in New Issue
Block a user