79 lines
2.3 KiB
TypeScript
79 lines
2.3 KiB
TypeScript
import sqlite from "sqlite3";
|
|
import bcrypt from "bcryptjs";
|
|
import { PHASE_PRODUCTION_BUILD } from "next/dist/shared/lib/constants";
|
|
|
|
export const database = (type: 'credentials'|'aliases') => {
|
|
if (process.env.NEXT_PHASE != PHASE_PRODUCTION_BUILD) {
|
|
for (const v of ["CREDENTIALS_DB_PATH", "ALIASES_DB_PATH"]) {
|
|
if (!process.env[v]) {
|
|
throw `$${v} not provided; unable to connect to database`;
|
|
}
|
|
}
|
|
}
|
|
|
|
const dbPath = type == 'credentials'
|
|
? process.env["CREDENTIALS_DB_PATH"]
|
|
: process.env["ALIASES_DB_PATH"];
|
|
|
|
return new sqlite.Database(dbPath!, (err: any) => {
|
|
if (err && process.env.NEXT_PHASE != PHASE_PRODUCTION_BUILD) throw err;
|
|
});
|
|
};
|
|
|
|
export function validateCredentials(email: string, password: string) {
|
|
const db = database('credentials');
|
|
|
|
return new Promise<boolean>((resolve, reject) => {
|
|
db.get(
|
|
"SELECT key, value FROM passwords WHERE key = ?",
|
|
email,
|
|
async (err, row: any) => {
|
|
db.close(); // We don't need this anymore
|
|
|
|
if (err) return reject(err);
|
|
if (!row) return resolve(false);
|
|
|
|
try {
|
|
const hash: string = row.value.replace("bcrypt:", "");
|
|
const isValid = await bcrypt.compare(password, hash);
|
|
resolve(isValid);
|
|
} catch(e) {
|
|
reject(e);
|
|
}
|
|
}
|
|
);
|
|
});
|
|
}
|
|
|
|
export function setUserPassword(email: string, newPass: string) {
|
|
return new Promise<void>(async (resolve, reject) => {
|
|
const db = database('credentials');
|
|
const hash = 'bcrypt:' + await bcrypt.hash(newPass, 10);
|
|
|
|
db.run("UPDATE passwords SET value = $1 WHERE key = $2",
|
|
{ 1: hash, 2: email },
|
|
async (err: any, res: any) => {
|
|
db.close();
|
|
if (err) return reject(err);
|
|
console.log(res);
|
|
resolve();
|
|
});
|
|
});
|
|
}
|
|
|
|
export type AliasEntry = { id: number, address: string, alias: string, pending: boolean };
|
|
export function getUserAliases(email: string) {
|
|
return new Promise<AliasEntry[]>(async (resolve, reject) => {
|
|
const db = database('aliases');
|
|
|
|
db.all("SELECT id, address, alias, pending FROM aliases WHERE address = ?", email, (err, res: any[]) => {
|
|
db.close();
|
|
if (err) return reject(err);
|
|
resolve(res.map((data) => ({
|
|
...data,
|
|
pending: !!data.pending,
|
|
})));
|
|
});
|
|
});
|
|
}
|