3
0
Fork 0
mirror of https://github.com/ZeppelinBot/Zeppelin.git synced 2025-05-10 04:25:01 +00:00
zeppelin/backend/src/data/ApiLogins.ts
2022-04-23 13:14:08 +03:00

105 lines
2.7 KiB
TypeScript

import crypto from "crypto";
import moment from "moment-timezone";
import { getRepository, Repository } from "typeorm";
// tslint:disable-next-line:no-submodule-imports
import uuidv4 from "uuid/v4";
import { DAYS, DBDateFormat } from "../utils";
import { BaseRepository } from "./BaseRepository";
import { ApiLogin } from "./entities/ApiLogin";
const LOGIN_EXPIRY_TIME = 1 * DAYS;
export class ApiLogins extends BaseRepository {
private apiLogins: Repository<ApiLogin>;
constructor() {
super();
this.apiLogins = getRepository(ApiLogin);
}
async getUserIdByApiKey(apiKey: string): Promise<string | null> {
const [loginId, token] = apiKey.split(".");
if (!loginId || !token) {
return null;
}
const login = await this.apiLogins
.createQueryBuilder()
.where("id = :id", { id: loginId })
.andWhere("expires_at > NOW()")
.getOne();
if (!login) {
return null;
}
const hash = crypto.createHash("sha256");
hash.update(loginId + token); // Remember to use loginId as the salt
const hashedToken = hash.digest("hex");
if (hashedToken !== login.token) {
return null;
}
return login.user_id;
}
async addLogin(userId: string): Promise<string> {
// Generate random login id
let loginId;
while (true) {
loginId = uuidv4();
const existing = await this.apiLogins.findOne({
where: {
id: loginId,
},
});
if (!existing) break;
}
// Generate token
const token = uuidv4();
const hash = crypto.createHash("sha256");
hash.update(loginId + token); // Use loginId as a salt
const hashedToken = hash.digest("hex");
// Save this to the DB
await this.apiLogins.insert({
id: loginId,
token: hashedToken,
user_id: userId,
logged_in_at: moment.utc().format(DBDateFormat),
expires_at: moment.utc().add(LOGIN_EXPIRY_TIME, "ms").format(DBDateFormat),
});
return `${loginId}.${token}`;
}
expireApiKey(apiKey) {
const [loginId, token] = apiKey.split(".");
if (!loginId || !token) return;
return this.apiLogins.update(
{ id: loginId },
{
expires_at: moment.utc().format(DBDateFormat),
},
);
}
async refreshApiKeyExpiryTime(apiKey) {
const [loginId, token] = apiKey.split(".");
if (!loginId || !token) return;
const updatedTime = moment().utc().add(LOGIN_EXPIRY_TIME, "ms");
const login = await this.apiLogins.createQueryBuilder().where("id = :id", { id: loginId }).getOne();
if (!login || moment.utc(login.expires_at).isSameOrAfter(updatedTime)) return;
await this.apiLogins.update(
{ id: loginId },
{
expires_at: updatedTime.format(DBDateFormat),
},
);
}
}