Vectrum
Sign In
35 lines · 1.4 KB · JavaScript
// Links sent by email (lib/emails.ts): "verify" confirms an address, "reset" sets a new password.
//
// Only a SHA-256 hash of the token in the link is stored. `email` is the address it went to, so a
// link stops working once the account's email changes. Only the server (a superuser) reads them.

migrate(
  (app) => {
    const users = app.findCollectionByNameOrId("users");
    const collection = new Collection({
      type: "base",
      name: "email_tokens",
      listRule: null,
      viewRule: null,
      createRule: null,
      updateRule: null,
      deleteRule: null,
      fields: [
        { type: "relation", name: "user", collectionId: users.id, maxSelect: 1, required: true, cascadeDelete: true },
        { type: "select", name: "purpose", values: ["verify", "reset"], maxSelect: 1, required: true },
        { type: "text", name: "email", max: 200, required: true },
        { type: "text", name: "token_hash", max: 64, required: true },
        { type: "number", name: "expires_at", onlyInt: true, min: 0, required: true },
        { type: "number", name: "created_at", onlyInt: true, min: 0, required: true },
      ],
      indexes: [
        "CREATE UNIQUE INDEX idx_email_tokens_hash ON email_tokens (token_hash)",
        "CREATE INDEX idx_email_tokens_user ON email_tokens (user, purpose)",
      ],
    });
    app.save(collection);
  },
  (app) => {
    app.delete(app.findCollectionByNameOrId("email_tokens"));
  },
);