@absolutejs/auth 0.79.0 → 0.80.1

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.
@@ -1,3 +1,4 @@
1
+ import type { AnyPgDatabase } from '../stores/postgres';
1
2
  import type { JsonObject } from '../types';
2
3
  import type { AuthSessionStore, SessionUserDecoder } from './types';
3
4
  export declare const authSessionsTable: import("drizzle-orm/pg-core").PgTableWithColumns<{
@@ -571,4 +572,7 @@ export declare const authSessionSchema: {
571
572
  }>;
572
573
  };
573
574
  export type AuthSessionSchema = typeof authSessionSchema;
575
+ /** Convenience adapter for Neon HTTP. Use createPostgresAuthSessionStore with
576
+ * your existing Drizzle client for Bun SQL, node-postgres, or postgres.js. */
574
577
  export declare const createNeonAuthSessionStore: <UserType>(databaseUrl: string, decodeUser: SessionUserDecoder<UserType>) => AuthSessionStore<UserType>;
578
+ export declare const createPostgresAuthSessionStore: <UserType, DB extends AnyPgDatabase>(db: DB, decodeUser: SessionUserDecoder<UserType>) => AuthSessionStore<UserType>;
@@ -0,0 +1,103 @@
1
+ # Persistent email/password sign-in (Bun + Elysia 2)
2
+
3
+ Use this credentials-only setup instead of the social-login manifest recipe.
4
+ The same API pattern passed synthetic browser signup, login, logout, booking and
5
+ full-container restart tests in Studio using auth 0.80.0. The example deliberately
6
+ sends no email and refuses production. For a real business configure email
7
+ verification, delivery, password policy, backups and the application's user schema.
8
+
9
+ Install published auth and a compatible Drizzle release. Set AUTH_DATABASE_URL
10
+ securely to a real isolated PostgreSQL database; never substitute a placeholder.
11
+ The application owns user records. The auth package owns credentials and sessions.
12
+
13
+ ```ts
14
+ import { auth } from '@absolutejs/auth/server';
15
+ import { createPostgresAuthSessionStore, createPostgresCredentialStore, runMigrations } from '@absolutejs/auth';
16
+ import { SQL } from 'bun';
17
+ import { Database } from 'bun:sqlite';
18
+ import { drizzle } from 'drizzle-orm/bun-sql';
19
+ import { mkdirSync } from 'node:fs';
20
+
21
+ if (process.env.NODE_ENV === 'production') throw new Error('Synthetic example: configure verified email and real business policy before production');
22
+ type Customer = { id: string; email: string };
23
+ const databaseUrl = process.env.AUTH_DATABASE_URL;
24
+ if (!databaseUrl)
25
+ throw new Error(
26
+ "AUTH_DATABASE_URL must point to the isolated acceptance database",
27
+ );
28
+ const migrationClient = new SQL({ url: databaseUrl, max: 1, prepare: false });
29
+ try {
30
+ await runMigrations({
31
+ blocks: ["sessions", "credentials"],
32
+ client: {
33
+ query: async (text, values) => ({
34
+ rows: await migrationClient.unsafe(text, values ? [...values] : []),
35
+ }),
36
+ },
37
+ log: () => undefined,
38
+ });
39
+ } finally {
40
+ await migrationClient.close();
41
+ }
42
+ const authDb = drizzle({ client: new SQL(databaseUrl) });
43
+ const decodeCustomer = (value: unknown): Customer => {
44
+ if (typeof value !== "object" || value === null)
45
+ throw new Error("Invalid customer session");
46
+ const id: unknown = Reflect.get(value, "id");
47
+ const email: unknown = Reflect.get(value, "email");
48
+ if (typeof id !== "string" || typeof email !== "string")
49
+ throw new Error("Invalid customer session");
50
+ return { id, email };
51
+ };
52
+ mkdirSync(".data", { recursive: true });
53
+ const db = new Database(".data/customer-example.sqlite", { create: true });
54
+ db.exec(
55
+ "PRAGMA journal_mode=WAL; PRAGMA busy_timeout=5000; CREATE TABLE IF NOT EXISTS customers(id TEXT PRIMARY KEY, email TEXT NOT NULL UNIQUE);",
56
+ );
57
+ const userById = db.query<Customer, [string]>(
58
+ "SELECT id,email FROM customers WHERE id=?",
59
+ );
60
+ const userByEmail = db.query<Customer, [string]>(
61
+ "SELECT id,email FROM customers WHERE email=?",
62
+ );
63
+ const insertUser = db.query("INSERT INTO customers(id,email) VALUES(?,?)");
64
+ const sessions = createPostgresAuthSessionStore(authDb, decodeCustomer);
65
+ export const authentication = await auth<Customer>({
66
+ providersConfiguration: {},
67
+ getUser: (id) => userById.get(String(id)) ?? null,
68
+ authSessionStore: sessions,
69
+ cookieSecure: true,
70
+ credentials: {
71
+ credentialStore: createPostgresCredentialStore(authDb),
72
+ getUserByEmail: (email) => userByEmail.get(email) ?? null,
73
+ onCreateCredentialUser: ({ email }) => {
74
+ const user = { id: crypto.randomUUID(), email };
75
+ insertUser.run(user.id, email);
76
+ return user;
77
+ },
78
+ // Local synthetic mode deliberately delivers no messages.
79
+ onSendEmail: () => undefined,
80
+ requireEmailVerification: false,
81
+ passwordPolicy: { minLength: 12, checkBreaches: false },
82
+ },
83
+ });
84
+
85
+ ```
86
+
87
+ Important API details:
88
+
89
+ - `auth` is asynchronous and comes from `@absolutejs/auth/server`.
90
+ - `authSessionStore` is top-level. `credentialStore` and credential callbacks
91
+ belong inside `credentials`. There is no top-level `sessionStore` option.
92
+ - Stores do not have `.runMigrations()`. Import `runMigrations` from the package
93
+ root and supply its query client as shown above.
94
+ - With Drizzle 1's Bun driver use `drizzle({ client })`, not `drizzle(client)`.
95
+ - Keep `prepare: false` on the migration client only. Application queries need
96
+ Bun's default prepared mode to encode JSON session data correctly.
97
+ - The built-in sign-out route is `DELETE /oauth2/signout`.
98
+ - Use `createAuthContext<Customer>()` from `/server` to read typed authenticated
99
+ users. Business APIs must check the session server-side and scope records to
100
+ that user. Do not implement a second password or cookie system.
101
+ - Preserve cookie headers when exposing a narrow typed JSON wrapper around the
102
+ package's configurable credential routes. Never store session tokens in browser
103
+ localStorage. Browser business requests belong in typed Eden + React Query.
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.79.0",
2
+ "version": "0.80.1",
3
3
  "name": "@absolutejs/auth",
4
4
  "description": "An authorization library for absolutejs",
5
5
  "repository": {