setupServerAdmin.ts 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. import { generateId, invalidateAllSessions } from "@server/auth/sessions/app";
  2. import { hashPassword, verifyPassword } from "@server/auth/password";
  3. import config from "@server/lib/config";
  4. import db from "@server/db";
  5. import { users } from "@server/db/schema";
  6. import logger from "@server/logger";
  7. import { eq } from "drizzle-orm";
  8. import moment from "moment";
  9. import { fromError } from "zod-validation-error";
  10. import { passwordSchema } from "@server/auth/passwordSchema";
  11. export async function setupServerAdmin() {
  12. const {
  13. server_admin: { email, password }
  14. } = config.getRawConfig().users;
  15. const parsed = passwordSchema.safeParse(password);
  16. if (!parsed.success) {
  17. throw Error(
  18. `Invalid server admin password: ${fromError(parsed.error).toString()}`
  19. );
  20. }
  21. const passwordHash = await hashPassword(password);
  22. await db.transaction(async (trx) => {
  23. try {
  24. const [existing] = await trx
  25. .select()
  26. .from(users)
  27. .where(eq(users.email, email));
  28. if (existing) {
  29. const passwordChanged = !(await verifyPassword(
  30. password,
  31. existing.passwordHash
  32. ));
  33. if (passwordChanged) {
  34. await trx
  35. .update(users)
  36. .set({ passwordHash })
  37. .where(eq(users.userId, existing.userId));
  38. // this isn't using the transaction, but it's probably fine
  39. await invalidateAllSessions(existing.userId);
  40. logger.info(`Server admin (${email}) password updated`);
  41. }
  42. if (existing.serverAdmin) {
  43. logger.info(`Server admin (${email}) already exists`)
  44. return;
  45. }
  46. await trx.update(users).set({ serverAdmin: false });
  47. await trx
  48. .update(users)
  49. .set({
  50. serverAdmin: true
  51. })
  52. .where(eq(users.email, email));
  53. logger.info(`Server admin (${email}) set`);
  54. return;
  55. }
  56. const userId = generateId(15);
  57. await trx.update(users).set({ serverAdmin: false });
  58. await db.insert(users).values({
  59. userId: userId,
  60. email: email,
  61. passwordHash,
  62. dateCreated: moment().toISOString(),
  63. serverAdmin: true,
  64. emailVerified: true
  65. });
  66. logger.info(`Server admin (${email}) created`);
  67. } catch (e) {
  68. logger.error(e);
  69. trx.rollback();
  70. }
  71. });
  72. }