Initial import of zappier-edge from zapier monorepo

This commit is contained in:
George Lambert 2026-09-11 16:05:17 -04:00
commit 2e035b1e80
128 changed files with 20545 additions and 0 deletions

75
src/admin-users.ts Normal file
View file

@ -0,0 +1,75 @@
import { randomBytes } from 'crypto';
import { hashPassword } from './accounts';
/**
* Admin-console accounts. Replaces the original static two-account env map
* with a persisted table; the env values remain the seed for empty databases.
*/
export interface AdminUser {
id: string; // usr_<hex>
username: string;
passwordHash: string;
active: boolean;
createdMs: number;
}
export interface AdminUserRepo {
list(): AdminUser[];
findByUsername(username: string): AdminUser | undefined;
save(user: AdminUser): void;
}
export function newAdminUserId(): string {
return `usr_${randomBytes(6).toString('hex')}`;
}
/** The env-backed seed accounts (preserved from the pre-table behavior). */
export function seedAdminUsersFromEnv(): { username: string; password: string }[] {
return [
{
username: process.env.ADMIN_USER ?? 'admin',
password: process.env.ADMIN_KEY ?? 'admin-dev-key',
},
{
username: process.env.DEMO_ADMIN_USER ?? 'demo',
password: process.env.DEMO_ADMIN_PASSWORD ?? '$$$Adm1n###',
},
];
}
export function makeAdminUser(username: string, password: string): AdminUser {
return {
id: newAdminUserId(),
username,
passwordHash: hashPassword(password),
active: true,
createdMs: Date.now(),
};
}
export class InMemoryAdminUserRepo implements AdminUserRepo {
private users: AdminUser[];
private constructor(users: AdminUser[]) {
this.users = users.map((u) => ({ ...u }));
}
static seeded(seed: { username: string; password: string }[]): InMemoryAdminUserRepo {
return new InMemoryAdminUserRepo(seed.map((s) => makeAdminUser(s.username, s.password)));
}
list(): AdminUser[] {
return [...this.users];
}
findByUsername(username: string): AdminUser | undefined {
return this.users.find((u) => u.username === username);
}
save(user: AdminUser): void {
const i = this.users.findIndex((u) => u.id === user.id || u.username === user.username);
if (i >= 0) this.users[i] = user;
else this.users.push(user);
}
}