Skip to content

Commit

Permalink
Merge pull request #45 from donghquinn/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
donghquinn authored Feb 17, 2024
2 parents eeb96a0 + 67fa262 commit d270c7d
Show file tree
Hide file tree
Showing 49 changed files with 285 additions and 417 deletions.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file removed .yarn/cache/jwa-npm-1.4.1-4f19d6572c-0bc002b71d.zip
Binary file not shown.
Binary file removed .yarn/cache/jws-npm-3.2.2-c1ae59c7af-70b016974a.zip
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
18 changes: 16 additions & 2 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,21 @@
---
version: '3.7'
services:
redis:
image: redis:7.0.15
container_name: gpt_redis
expose:
- ${REDIS_PORT}
volumes:
- ./redis.conf:/etc/redis/redis.conf
- ./redis_data:/data\
command: redis-server --requirepass ${REDIS_PASS}
networks:
- proxy

backend:
depends_on:
- redis
image: ${REGISTRY_URL}
# build:
# context: .
Expand All @@ -19,8 +33,8 @@ services:
reservations:
cpus: '0.15'
memory: 300M
# expose:
# - ${APP_PORT}
expose:
- ${APP_PORT}
env_file:
- .env
networks:
Expand Down
18 changes: 7 additions & 11 deletions package-deploy.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,41 +10,37 @@
"schema": "prisma generate"
},
"dependencies": {
"@nestjs/common": "^10.3.1",
"@nestjs/core": "^10.3.1",
"@nestjs/jwt": "^10.2.0",
"@nestjs/passport": "^10.0.3",
"@nestjs/platform-express": "^10.3.1",
"@nestjs/common": "^10.3.3",
"@nestjs/core": "^10.3.3",
"@nestjs/platform-express": "^10.3.3",
"@prisma/client": "^5.9.1",
"cookie-parser": "^1.4.6",
"date-fns": "^2.30.0",
"express": "^4.18.2",
"helmet": "^7.1.0",
"moment-timezone": "^0.5.43",
"node-fetch": "^3.3.2",
"passport": "^0.7.0",
"passport-jwt": "^4.0.1",
"prisma": "^5.9.1",
"redis": "^4.6.13",
"reflect-metadata": "^0.2.1",
"rxjs": "^7.8.1",
"set-interval-async": "^3.0.3",
"winston": "^3.11.0",
"winston-daily-rotate-file": "^4.7.1",
"zod": "^3.22.4"
},
"devDependencies": {
"@types/cookie-parser": "^1",
"@types/express": "^4.17.21",
"@types/node": "^20.11.16",
"@types/passport": "^0",
"@types/passport-jwt": "^4",
"@types/node": "^20.11.19",
"@typescript-eslint/eslint-plugin": "^6.19.0",
"@typescript-eslint/parser": "^6.19.0",
"eslint": "^8.56.0",
"eslint-config-airbnb-base": "^15.0.0",
"eslint-config-airbnb-typescript": "^17.1.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-import": "^2.29.1",
"prettier": "^3.2.2",
"prettier": "^3.2.5",
"ts-node": "^10.9.2",
"ts-paths-esm-loader": "^1.4.3",
"tsconfig-paths": "^4.2.0",
Expand Down
18 changes: 7 additions & 11 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,41 +15,37 @@
"db:update": "prisma db push"
},
"dependencies": {
"@nestjs/common": "^10.3.1",
"@nestjs/core": "^10.3.1",
"@nestjs/jwt": "^10.2.0",
"@nestjs/passport": "^10.0.3",
"@nestjs/platform-express": "^10.3.1",
"@nestjs/common": "^10.3.3",
"@nestjs/core": "^10.3.3",
"@nestjs/platform-express": "^10.3.3",
"@prisma/client": "^5.9.1",
"cookie-parser": "^1.4.6",
"date-fns": "^2.30.0",
"express": "^4.18.2",
"helmet": "^7.1.0",
"moment-timezone": "^0.5.43",
"node-fetch": "^3.3.2",
"passport": "^0.7.0",
"passport-jwt": "^4.0.1",
"prisma": "^5.9.1",
"redis": "^4.6.13",
"reflect-metadata": "^0.2.1",
"rxjs": "^7.8.1",
"set-interval-async": "^3.0.3",
"winston": "^3.11.0",
"winston-daily-rotate-file": "^4.7.1",
"zod": "^3.22.4"
},
"devDependencies": {
"@types/cookie-parser": "^1",
"@types/express": "^4.17.21",
"@types/node": "^20.11.16",
"@types/passport": "^0",
"@types/passport-jwt": "^4",
"@types/node": "^20.11.19",
"@typescript-eslint/eslint-plugin": "^6.19.0",
"@typescript-eslint/parser": "^6.19.0",
"eslint": "^8.56.0",
"eslint-config-airbnb-base": "^15.0.0",
"eslint-config-airbnb-typescript": "^17.1.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-import": "^2.29.1",
"prettier": "^3.2.2",
"prettier": "^3.2.5",
"ts-node": "^10.9.2",
"ts-paths-esm-loader": "^1.4.3",
"tsconfig-paths": "^4.2.0",
Expand Down
13 changes: 13 additions & 0 deletions src/errors/redis.error.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export class RedisError extends Error {
type: string;

constructor(type: string, message: string, cause?: Error) {
super(message);

this.type = type;

this.name = 'Redis Error';

this.cause = cause;
}
}
20 changes: 0 additions & 20 deletions src/middlewares/jwt-access.middleware.ts

This file was deleted.

155 changes: 109 additions & 46 deletions src/providers/auth/account-manager.pvd.ts
Original file line number Diff line number Diff line change
@@ -1,36 +1,46 @@
import { RedisError } from '@errors/redis.error';
import { Injectable } from '@nestjs/common';
import { ClientLogger, ManagerLogger } from '@utils/logger.util';
import { ClientLoginMapItem, ClientLoginMapKey } from 'types/client.type';
import { RedisClientType, createClient } from 'redis';
import { clearIntervalAsync, setIntervalAsync } from 'set-interval-async';
import { ClientLoginMapItem } from 'types/client.type';

@Injectable()
export class AccountManager {
private userMap: WeakMap<ClientLoginMapKey, ClientLoginMapItem>;
private redis: RedisClientType;

private userKeys: Array<ClientLoginMapKey>;
private keyList: Array<string>;

private redisUrl: string;

constructor() {
this.userKeys = [];
this.userMap = new WeakMap();
// eslint-disable-next-line max-len
this.redisUrl = `redis://${process.env.REDIS_USER}:${process.env.REDIS_PASS}@${process.env.REDIS_HOST}:${process.env.REDIS_PORT}`;

this.redis = createClient({
url: this.redisUrl,
username: process.env.REDIS_USER,
password: process.env.REDIS_PASS,
});

this.keyList = [];
}

public setLoginUser(clientUuid: string, email: string, password?: string) {
const isLogined = this.getItem(clientUuid);
public async setLoginUser(clientUuid: string, email: string, password: string) {
const isLogined = this.getItem(email);

ManagerLogger.debug('[ACCOUNT] Searching User Info: %o', {
isLogined,
map: this.userMap,
clientUuid,
});

if (!isLogined) {
const clientKey = { uuid: clientUuid };

this.userKeys.push(clientKey);
this.setItem(email, clientKey, password);
if (isLogined === null) {
this.keyList.push(email);
await this.setItem(email, clientUuid, password);

if (this.userKeys.length >= 5000) {
if (this.keyList.length >= 5000) {
ClientLogger.debug('[AccountManager] keyList maximum reached. shift()');
this.userKeys.shift();
this.keyList.shift();
}

ClientLogger.info('[ACCOUNT] Set Finished');
Expand All @@ -40,86 +50,139 @@ export class AccountManager {

ManagerLogger.debug('[ACCOUNT] Found User Key: %o', {
clientUuid,
map: this.userMap,
});

const interval = 1000 * 60 * 10;

const timer = setInterval(() => {
const isExsit = this.getItem(clientUuid);
const timer = setIntervalAsync(async () => {
const isExsit = await this.getItem(email);

if (!isExsit) {
if (isExsit === null) {
ManagerLogger.info('[ACCOUNT] It is not existing user. Clear Interval.');

ManagerLogger.debug('[ACCOUNT] Client Map Inspection: %o', {
isExsit,
clientUuid,
map: this.userMap,
});

clearInterval(timer);
clearIntervalAsync(timer);
} else {
ManagerLogger.info('[ACCOUNT] Expiration time. Delete user.');

ManagerLogger.debug('[ACCOUNT] Client Map Inspection: %o', {
clientUuid,
map: this.userMap,
});

this.deleteItem(clientUuid);
await this.deleteItem(email);
}
}, interval);

return clientUuid;
}

public deleteLogoutUser(clientUuid: string) {
public async deleteLogoutUser(email: string) {
ManagerLogger.debug('[ACCOUNT] Client Data: %o', {
clientUuid,
map: this.userMap,
email,
});

const isExist = this.getItem(clientUuid);
const isExist = await this.getItem(email);

if (!isExist) {
if (isExist === null) {
ManagerLogger.info('[ACCOUNT] Not Matchin Data found. Ignore.');

return false;
}

this.deleteItem(clientUuid);
await this.deleteItem(email);

ManagerLogger.debug('[ACCOUNT] Client Map Delete Inspection: %o', {
clientUuid,
map: this.userMap,
email,
});

return true;
}

public deleteItem(clientUuid: string) {
const index = this.userKeys.findIndex((item) => item.uuid === clientUuid);
public async deleteItem(email: string) {
try {
const index = this.keyList.findIndex((item) => item === email);

if (index > -1) this.userKeys.splice(index, 1);
if (index > -1) {
this.keyList.splice(index, 1);
await this.redis.del(email);

ClientLogger.debug('[ACCOUNT] Delete Finished: %o', {
clientUuid,
index,
keyList: this.userKeys,
map: this.userMap,
});
ManagerLogger.info('[DELETE] Deleted User Info from Key List and Cache Data');
}

ManagerLogger.debug('[DELETE] Client Map Inspection: %o', {
email,
index,
// map: this.userMap,
userKey: this.keyList,
});
} catch (error) {
ManagerLogger.error('[DELETE] Delete User Item Error: %o', {
error,
});

throw new RedisError(
'[DELETE] Delete User Item',
'Delete User Item Error.',
error instanceof Error ? error : new Error(JSON.stringify(error)),
);
}
}

public setItem(email: string, clientKey: ClientLoginMapKey, password?: string) {
return this.userMap.set(clientKey, { email, password });
public async setItem(email: string, uuid: string, password: string) {
try {
// this.userMap.set( key, { uuid, address, privateKey, pkToken } );
await this.redis.set(email, JSON.stringify({ uuid, password }));
this.keyList.push(email);
} catch (error) {
ManagerLogger.error('[SET] User Info Error: %o', {
error,
});

throw new RedisError(
'[SET] User Info',
'Set User Info',
error instanceof Error ? error : new Error(JSON.stringify(error)),
);
}
}

public getItem(clientUuid: string) {
const key = this.userKeys.find((item) => item.uuid === clientUuid);
public async getItem(email: string) {
try {
const key = this.keyList.find((item) => item === email);

ManagerLogger.debug('[GET] Client Map Inspection: %o', {
email,
key,
// map: this.userMap,
userKey: this.keyList,
});

if (key === undefined) return null;

if (!key) return null;
ManagerLogger.info('[GET] Found key from keyList');

return this.userMap.get(key) as ClientLoginMapItem;
const gotItem = await this.redis.get(key);

if (gotItem === null) return null;

const returnData = JSON.parse(gotItem) as ClientLoginMapItem;

return returnData;
} catch (error) {
ManagerLogger.error('[GET] Get User Item Error: %o', {
error,
});

throw new RedisError(
'[GET] Get User Item',
'Get User Item Error.',
error instanceof Error ? error : new Error(JSON.stringify(error)),
);
}
}

// public stop() {
Expand Down
Loading

0 comments on commit d270c7d

Please sign in to comment.