@vonall/auth 0.4.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/README.md +14 -7
  3. package/dist/index.d.ts +1 -1
  4. package/dist/messages.d.ts +460 -16
  5. package/dist/messages.js +4 -14
  6. package/dist/remote/app_user.remote.d.ts +2 -2
  7. package/dist/remote/app_user.remote.js +13 -13
  8. package/dist/remote/einladung.remote.js +15 -12
  9. package/dist/server/{registry.d.ts → context.d.ts} +13 -16
  10. package/dist/server/context.js +22 -0
  11. package/dist/server/create.d.ts +27 -22
  12. package/dist/server/create.js +50 -33
  13. package/dist/server/index.d.ts +7 -7
  14. package/dist/server/index.js +6 -6
  15. package/dist/server/loads.d.ts +14 -2
  16. package/dist/server/loads.js +19 -14
  17. package/dist/server/repositories/EinladungRepo.d.ts +4 -1
  18. package/dist/server/repositories/EinladungRepo.js +66 -73
  19. package/dist/server/repositories/UserRepo.d.ts +4 -1
  20. package/dist/server/repositories/UserRepo.js +49 -57
  21. package/dist/server/service/einladung.service.d.ts +6 -2
  22. package/dist/server/service/einladung.service.js +56 -51
  23. package/dist/server/service/mail.d.ts +16 -12
  24. package/dist/server/service/mail.js +32 -34
  25. package/dist/testing/index.d.ts +6 -8
  26. package/dist/testing/index.js +16 -19
  27. package/dist/ui/AdminView.svelte +2 -1
  28. package/dist/ui/InvitationsTab.svelte +2 -1
  29. package/dist/ui/LoginForm.svelte +1 -1
  30. package/dist/ui/ResetPasswordForm.svelte +2 -2
  31. package/dist/ui/context.d.ts +6 -7
  32. package/dist/ui/context.js +15 -9
  33. package/dist/util/signup.d.ts +2 -0
  34. package/dist/util/signup.js +2 -0
  35. package/package.json +3 -2
  36. package/dist/server/registry.js +0 -22
@@ -1,15 +1,13 @@
1
+ import { type AuthSchema } from "../schema/index.js";
2
+ import type { AuthContext, Db } from "../server/context.js";
1
3
  import { type CreateAuthOptions } from "../server/create.js";
2
- import type { Db } from "../server/registry.js";
3
4
  /** Creates a user directly (the first one becomes admin, as in the app) and returns its id. */
4
- export declare function createUser(email?: string): Promise<string>;
5
+ export declare function createUser(ctx: AuthContext, email?: string): Promise<string>;
5
6
  /** The wiring with test values: every option on, mail off, unless overridden; as a Product's `src/lib/auth.ts` does it. */
6
- export declare function testAuth(db: Db, overrides?: Partial<CreateAuthOptions>): {
7
- handle: import("@sveltejs/kit/hooks").Handle;
7
+ export declare function testAuth(db: Db, overrides?: Partial<CreateAuthOptions<AuthSchema<true, true>>>): {
8
+ ctx: AuthContext<AuthSchema<boolean, boolean>>;
9
+ sessionHandle: import("@sveltejs/kit/hooks").Handle;
8
10
  apiHandler: import("@sveltejs/kit").RequestHandler;
9
- providers: {
10
- github: boolean;
11
- google: boolean;
12
- };
13
11
  auth: import("better-auth").Auth<{
14
12
  plugins: [{
15
13
  id: "two-factor";
@@ -7,30 +7,27 @@ import { sveltekitCookies } from "better-auth/svelte-kit";
7
7
  import { createMailer } from "@vonall/mail";
8
8
  import { ac, roles } from "../permissions.js";
9
9
  import { authSchema } from "../schema/index.js";
10
- import { authOptions, registerAuth } from "../server/create.js";
11
- import { UserRepo } from "../server/repositories/UserRepo.js";
10
+ import { createAuth } from "../server/create.js";
11
+ import { userRepo } from "../server/repositories/UserRepo.js";
12
12
  /** Creates a user directly (the first one becomes admin, as in the app) and returns its id. */
13
- export async function createUser(email = "user@example.com") {
13
+ export async function createUser(ctx, email = "user@example.com") {
14
14
  const id = crypto.randomUUID();
15
- await UserRepo.insertUser({ id, email, name: "", emailVerified: true, createdAt: new Date(), updatedAt: new Date() });
15
+ await userRepo(ctx).insertUser({ id, email, name: "", emailVerified: true, createdAt: new Date(), updatedAt: new Date() });
16
16
  return id;
17
17
  }
18
18
  /** The wiring with test values: every option on, mail off, unless overridden; as a Product's `src/lib/auth.ts` does it. */
19
19
  export function testAuth(db, overrides = {}) {
20
- const auth = betterAuth({
21
- ...authOptions({
22
- db,
23
- schema: authSchema({ admin: true, mcp: true }),
24
- secret: "test-secret-for-the-db-tests-only",
25
- origin: "http://localhost:5173",
26
- appName: "Test",
27
- locale: "en-GB",
28
- signupMode: "invite",
29
- mailer: createMailer({ smtp: null }),
30
- admin: true,
31
- ...overrides,
32
- }),
33
- plugins: [twoFactor(), adminPlugin({ ac, roles }), sveltekitCookies(getRequestEvent)],
20
+ const wiring = createAuth({
21
+ db,
22
+ schema: authSchema({ admin: true, mcp: true }),
23
+ secret: "test-secret-for-the-db-tests-only",
24
+ origin: "http://localhost:5173",
25
+ appName: "Test",
26
+ locale: "en-GB",
27
+ signupMode: "invite",
28
+ mailer: createMailer({ smtp: null }),
29
+ ...overrides,
34
30
  });
35
- return { auth, ...registerAuth(auth) };
31
+ const auth = betterAuth({ ...wiring.options, plugins: [twoFactor(), adminPlugin({ ac, roles }), sveltekitCookies(getRequestEvent)] });
32
+ return { auth, ...wiring.register(auth) };
36
33
  }
@@ -2,6 +2,7 @@
2
2
  import { Trash2, X } from "@lucide/svelte";
3
3
  import { toast } from "svelte-sonner";
4
4
  import { m } from "../messages.js";
5
+ import { EINLADUNG_GUELTIG_TAGE } from "../util/signup.js";
5
6
  import { deleteUser, getAllUsers, setUserRole } from "../remote/app_user.remote.js";
6
7
  import { adminWithdrawEinladung, getAlleEinladungen } from "../remote/einladung.remote.js";
7
8
  import { authUi } from "./context.js";
@@ -68,7 +69,7 @@
68
69
 
69
70
  <section class="panel grid gap-3 p-5">
70
71
  <span class="section-kicker">{m().invitations}</span>
71
- <p class="text-sm text-muted-foreground">{m().inviteIntro}</p>
72
+ <p class="text-sm text-muted-foreground">{m().inviteIntro(EINLADUNG_GUELTIG_TAGE)}</p>
72
73
  <EinladungErstellen />
73
74
  {#if einladungen.length === 0}
74
75
  <p class="text-sm text-muted-foreground">{m().noOpenInvitations}</p>
@@ -3,6 +3,7 @@
3
3
  import { toast } from "svelte-sonner";
4
4
  import * as Tabs from "../components/ui/tabs/index.js";
5
5
  import { m } from "../messages.js";
6
+ import { EINLADUNG_GUELTIG_TAGE } from "../util/signup.js";
6
7
  import { getOffeneEinladungen, withdrawEinladung } from "../remote/einladung.remote.js";
7
8
  import { authUi } from "./context.js";
8
9
  import EinladungErstellen from "./EinladungErstellen.svelte";
@@ -26,7 +27,7 @@
26
27
  <Tabs.Content value="invitations" class="panel mt-6 grid gap-4 p-6 md:p-8">
27
28
  <div class="space-y-1">
28
29
  <h3 class="text-lg font-medium">{m().inviteSomeone}</h3>
29
- <p class="text-sm text-muted-foreground">{m().inviteIntro}</p>
30
+ <p class="text-sm text-muted-foreground">{m().inviteIntro(EINLADUNG_GUELTIG_TAGE)}</p>
30
31
  </div>
31
32
 
32
33
  <EinladungErstellen />
@@ -54,7 +54,7 @@
54
54
  async function requestPasswordReset(e: SubmitEvent) {
55
55
  e.preventDefault();
56
56
  if (!forgotPasswordEmail || !forgotPasswordEmail.includes("@")) {
57
- toast.error(m().invalidEmailDot);
57
+ toast.error(m().invalidEmail);
58
58
  return;
59
59
  }
60
60
  sendingResetLink = true;
@@ -30,11 +30,11 @@
30
30
  return;
31
31
  }
32
32
  if (password.length < MIN_PASSWORD_LENGTH) {
33
- toast.error(m().passwordTooShortDot(MIN_PASSWORD_LENGTH));
33
+ toast.error(m().passwordTooShort(MIN_PASSWORD_LENGTH));
34
34
  return;
35
35
  }
36
36
  if (password !== confirmPassword) {
37
- toast.error(m().passwordsDontMatchDot);
37
+ toast.error(m().passwordsMismatch);
38
38
  return;
39
39
  }
40
40
  loading = true;
@@ -1,4 +1,4 @@
1
- import type { SignupMode } from "../types.js";
1
+ import type { AuthUiData } from "../server/loads.js";
2
2
  type Outcome<T = unknown> = Promise<{
3
3
  data?: T | null;
4
4
  error?: {
@@ -80,14 +80,13 @@ export type AuthClientLike = {
80
80
  providerId?: string;
81
81
  }): Outcome;
82
82
  };
83
- export type AuthUi = {
83
+ export type AuthUi = AuthUiData & {
84
84
  authClient: AuthClientLike;
85
- appName: string;
86
- /** For dates, e.g. "de-CH". */
87
- locale: string;
88
- signupMode: SignupMode;
89
85
  };
90
86
  /** In the Product's root layout. */
91
- export declare function setAuthUi(ui: AuthUi): AuthUi;
87
+ export declare function setAuthUi({ authClient }: {
88
+ authClient: AuthClientLike;
89
+ }): void;
90
+ /** In a component: the client, and the app's facts from the page data. */
92
91
  export declare function authUi(): AuthUi;
93
92
  export {};
@@ -1,17 +1,23 @@
1
1
  /**
2
- * What the auth components need from the Product, set once in its root layout (`setAuthUi({ … })` during component
3
- * init): the better-auth client (the Product builds it, see `src/lib/auth-client.ts`), the app's name, its locale and
4
- * signup mode.
2
+ * What the auth components need: the better-auth client, set once in the Product's root layout (`setAuthUi({ authClient })`
3
+ * during component init; the Product builds the client, see `src/lib/auth-client.ts`), and the app's name, locale
4
+ * and signup mode, which this package's loads put into the page data (`authUi` in `authLayoutLoad`, `homeLayoutLoad`,
5
+ * `einladungLoad`).
5
6
  */
6
7
  import { getContext, setContext } from "svelte";
8
+ import { page } from "$app/state";
7
9
  const KEY = Symbol("vonall-auth-ui");
8
10
  /** In the Product's root layout. */
9
- export function setAuthUi(ui) {
10
- return setContext(KEY, ui);
11
+ export function setAuthUi({ authClient }) {
12
+ setContext(KEY, authClient);
11
13
  }
14
+ /** In a component: the client, and the app's facts from the page data. */
12
15
  export function authUi() {
13
- const ui = getContext(KEY);
14
- if (!ui)
15
- throw new Error("@vonall/auth: setAuthUi({ authClient, appName, locale, signupMode }) has not run in the root layout");
16
- return ui;
16
+ const authClient = getContext(KEY);
17
+ if (!authClient)
18
+ throw new Error("@vonall/auth: setAuthUi({ authClient }) has not run in the root layout");
19
+ const data = page.data.authUi;
20
+ if (!data)
21
+ throw new Error("@vonall/auth: this page's data has no `authUi`; its load or its layout's must be one of this package's (authLayoutLoad, homeLayoutLoad, einladungLoad)");
22
+ return { authClient, ...data };
17
23
  }
@@ -1,4 +1,6 @@
1
1
  import type { SignupMode, SignupState } from "../types.js";
2
+ /** How long an Einladung's link works. */
3
+ export declare const EINLADUNG_GUELTIG_TAGE = 14;
2
4
  /** Whether a user is an admin. Works without the admin option too: the user then has no role and nobody is. */
3
5
  export declare function isAdmin(user: object | null | undefined): boolean;
4
6
  /** Whether a user may create Einladungen in this signup mode. */
@@ -1,3 +1,5 @@
1
+ /** How long an Einladung's link works. */
2
+ export const EINLADUNG_GUELTIG_TAGE = 14;
1
3
  /** Whether a user is an admin. Works without the admin option too: the user then has no role and nobody is. */
2
4
  export function isAdmin(user) {
3
5
  return Boolean(user && "role" in user && user.role === "admin");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vonall/auth",
3
- "version": "0.4.0",
3
+ "version": "0.6.0",
4
4
  "description": "Accounts for a Web App Factory Product: better-auth with the hooks, the protected helpers, Einladungen, Konto, the auth pages and the settings; Admin as an option",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -102,7 +102,8 @@
102
102
  "tailwind-merge": "^3.7.0",
103
103
  "tailwind-variants": "^3.3.1",
104
104
  "uqr": "^0.1.3",
105
- "@vonall/mail": "^0.1.1"
105
+ "@vonall/mail": "^0.2.0",
106
+ "@vonall/messages": "^0.1.0"
106
107
  },
107
108
  "scripts": {
108
109
  "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
@@ -1,22 +0,0 @@
1
- let current = null;
2
- export function setRegistry(registry) {
3
- current = registry;
4
- }
5
- export function registry() {
6
- if (!current)
7
- throw new Error("@vonall/auth: authOptions() has not run; import the app's auth wiring (src/lib/auth.ts) first");
8
- return current;
9
- }
10
- /** The Product's better-auth instance. */
11
- export function authInstance() {
12
- const auth = registry().auth;
13
- if (!auth)
14
- throw new Error("@vonall/auth: registerAuth(auth) has not run; the app's auth wiring (src/lib/auth.ts) calls it after betterAuth()");
15
- return auth;
16
- }
17
- export const consoleLog = {
18
- debug: () => { },
19
- info: (message, context) => console.info(message, context ?? ""),
20
- warn: (message, context) => console.warn(message, context ?? ""),
21
- error: (message, context, error) => console.error(message, context ?? "", error ?? ""),
22
- };