49 lines
1.4 KiB
TypeScript
49 lines
1.4 KiB
TypeScript
import bcrypt from "bcryptjs";
|
|
import jwt from "jsonwebtoken";
|
|
import { config } from "../config"
|
|
import { readDb, writeDb } from "../storage/jsondb"
|
|
import { nowIso } from "../utils/time"
|
|
import { User } from "../types"
|
|
|
|
const ensureSeedUser = async (): Promise<User | null> => {
|
|
if (!config.appUsername || !config.appPassword) {
|
|
return null;
|
|
}
|
|
const db = await readDb();
|
|
const existing = db.users.find((user) => user.username === config.appUsername);
|
|
if (existing) {
|
|
return existing;
|
|
}
|
|
const passwordHash = await bcrypt.hash(config.appPassword, 10);
|
|
const newUser: User = {
|
|
username: config.appUsername,
|
|
passwordHash,
|
|
createdAt: nowIso(),
|
|
};
|
|
db.users.push(newUser);
|
|
await writeDb(db);
|
|
return newUser;
|
|
};
|
|
|
|
export const initAuth = async () => {
|
|
await ensureSeedUser();
|
|
};
|
|
|
|
export const verifyCredentials = async (username: string, password: string) => {
|
|
const db = await readDb();
|
|
const user = db.users.find((u) => u.username === username);
|
|
if (!user) {
|
|
return null;
|
|
}
|
|
const match = await bcrypt.compare(password, user.passwordHash);
|
|
return match ? user : null;
|
|
};
|
|
|
|
export const signToken = (payload: { username: string }) => {
|
|
return jwt.sign(payload, config.jwtSecret, { expiresIn: "60d" });
|
|
};
|
|
|
|
export const verifyToken = (token: string) => {
|
|
return jwt.verify(token, config.jwtSecret) as { username: string };
|
|
};
|