@seamless-auth/express 0.0.2-beta.1 → 0.0.2-beta.11

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 (40) hide show
  1. package/LICENSE +79 -0
  2. package/LICENSE.md +26 -0
  3. package/README.md +102 -123
  4. package/dist/index.d.ts +190 -7
  5. package/dist/index.js +501 -5
  6. package/package.json +31 -14
  7. package/dist/createServer.d.ts +0 -48
  8. package/dist/createServer.d.ts.map +0 -1
  9. package/dist/createServer.js +0 -164
  10. package/dist/index.d.ts.map +0 -1
  11. package/dist/internal/authFetch.d.ts +0 -9
  12. package/dist/internal/authFetch.d.ts.map +0 -1
  13. package/dist/internal/authFetch.js +0 -37
  14. package/dist/internal/cookie.d.ts +0 -11
  15. package/dist/internal/cookie.d.ts.map +0 -1
  16. package/dist/internal/cookie.js +0 -28
  17. package/dist/internal/getSeamlessUser.d.ts +0 -51
  18. package/dist/internal/getSeamlessUser.d.ts.map +0 -1
  19. package/dist/internal/getSeamlessUser.js +0 -72
  20. package/dist/internal/refreshAccessToken.d.ts +0 -10
  21. package/dist/internal/refreshAccessToken.d.ts.map +0 -1
  22. package/dist/internal/refreshAccessToken.js +0 -44
  23. package/dist/internal/verifyCookieJwt.d.ts +0 -2
  24. package/dist/internal/verifyCookieJwt.d.ts.map +0 -1
  25. package/dist/internal/verifyCookieJwt.js +0 -13
  26. package/dist/internal/verifySignedAuthResponse.d.ts +0 -6
  27. package/dist/internal/verifySignedAuthResponse.d.ts.map +0 -1
  28. package/dist/internal/verifySignedAuthResponse.js +0 -23
  29. package/dist/middleware/ensureCookies.d.ts +0 -8
  30. package/dist/middleware/ensureCookies.d.ts.map +0 -1
  31. package/dist/middleware/ensureCookies.js +0 -78
  32. package/dist/middleware/requireAuth.d.ts +0 -53
  33. package/dist/middleware/requireAuth.d.ts.map +0 -1
  34. package/dist/middleware/requireAuth.js +0 -118
  35. package/dist/middleware/requireRole.d.ts +0 -49
  36. package/dist/middleware/requireRole.d.ts.map +0 -1
  37. package/dist/middleware/requireRole.js +0 -77
  38. package/dist/types.d.ts +0 -9
  39. package/dist/types.d.ts.map +0 -1
  40. package/dist/types.js +0 -1
package/dist/index.js CHANGED
@@ -1,5 +1,501 @@
1
- import { createSeamlessAuthServer } from './createServer.js';
2
- export { requireAuth } from './middleware/requireAuth.js';
3
- export { requireRole } from './middleware/requireRole.js';
4
- export { getSeamlessUser } from './internal/getSeamlessUser.js';
5
- export default createSeamlessAuthServer;
1
+ // src/createServer.ts
2
+ import express from "express";
3
+ import cookieParser from "cookie-parser";
4
+
5
+ // src/middleware/ensureCookies.ts
6
+ import { ensureCookies } from "@seamless-auth/core";
7
+
8
+ // src/internal/cookie.ts
9
+ import jwt from "jsonwebtoken";
10
+ function setSessionCookie(res, opts, signer) {
11
+ const token = jwt.sign(opts.payload, signer.secret, {
12
+ algorithm: "HS256",
13
+ expiresIn: `${opts.ttlSeconds}s`
14
+ });
15
+ res.cookie(opts.name, token, {
16
+ httpOnly: true,
17
+ secure: signer.secure,
18
+ sameSite: signer.sameSite,
19
+ path: "/",
20
+ domain: opts.domain,
21
+ maxAge: Number(opts.ttlSeconds) * 1e3
22
+ });
23
+ }
24
+ function clearSessionCookie(res, domain, name) {
25
+ res.clearCookie(name, { domain, path: "/" });
26
+ }
27
+ function clearAllCookies(res, domain, ...cookieNames) {
28
+ for (const name of cookieNames) {
29
+ res.clearCookie(name, { domain, path: "/" });
30
+ }
31
+ }
32
+
33
+ // src/middleware/ensureCookies.ts
34
+ function createEnsureCookiesMiddleware(opts) {
35
+ if (!opts.cookieSecret) {
36
+ throw new Error("Missing cookieSecret");
37
+ }
38
+ if (!opts.serviceSecret) {
39
+ throw new Error("Missing serviceSecret");
40
+ }
41
+ const cookieSigner = {
42
+ secret: opts.cookieSecret,
43
+ secure: process.env.NODE_ENV === "production",
44
+ sameSite: process.env.NODE_ENV === "production" ? "none" : "lax"
45
+ };
46
+ return async function ensureCookiesMiddleware(req, res, next) {
47
+ const result = await ensureCookies(
48
+ {
49
+ path: req.path,
50
+ cookies: req.cookies ?? {}
51
+ },
52
+ {
53
+ authServerUrl: opts.authServerUrl,
54
+ cookieDomain: opts.cookieDomain,
55
+ accessCookieName: opts.accessCookieName,
56
+ registrationCookieName: opts.registrationCookieName,
57
+ refreshCookieName: opts.refreshCookieName,
58
+ preAuthCookieName: opts.preAuthCookieName,
59
+ cookieSecret: opts.cookieSecret,
60
+ serviceSecret: opts.serviceSecret,
61
+ issuer: opts.issuer,
62
+ audience: opts.audience,
63
+ keyId: opts.keyId
64
+ }
65
+ );
66
+ applyResult(res, req, result, opts, cookieSigner);
67
+ if (result.type === "error") return;
68
+ next();
69
+ };
70
+ }
71
+ function applyResult(res, req, result, opts, cookieSigner) {
72
+ if (result.clearCookies?.length) {
73
+ clearAllCookies(res, opts.cookieDomain, ...result.clearCookies);
74
+ }
75
+ if (result.setCookies) {
76
+ for (const c of result.setCookies) {
77
+ setSessionCookie(
78
+ res,
79
+ {
80
+ name: c.name,
81
+ payload: c.value,
82
+ domain: c.domain,
83
+ ttlSeconds: c.ttl
84
+ },
85
+ cookieSigner
86
+ );
87
+ }
88
+ }
89
+ if (result.user) {
90
+ req.cookiePayload = result.user;
91
+ }
92
+ if (result.type === "error") {
93
+ res.status(result.status ?? 401).json({ error: result.error });
94
+ }
95
+ }
96
+
97
+ // src/handlers/login.ts
98
+ import { loginHandler } from "@seamless-auth/core/handlers/login";
99
+ async function login(req, res, opts) {
100
+ const cookieSigner = {
101
+ secret: opts.cookieSecret,
102
+ secure: process.env.NODE_ENV === "production",
103
+ sameSite: process.env.NODE_ENV === "production" ? "none" : "lax"
104
+ };
105
+ const result = await loginHandler(
106
+ { body: req.body },
107
+ {
108
+ authServerUrl: opts.authServerUrl,
109
+ cookieDomain: opts.cookieDomain,
110
+ preAuthCookieName: opts.preAuthCookieName
111
+ }
112
+ );
113
+ if (!cookieSigner.secret) {
114
+ throw new Error("Missing COOKIE_SIGNING_KEY");
115
+ }
116
+ if (result.setCookies) {
117
+ for (const c of result.setCookies) {
118
+ setSessionCookie(
119
+ res,
120
+ {
121
+ name: c.name,
122
+ payload: c.value,
123
+ domain: c.domain,
124
+ ttlSeconds: c.ttl
125
+ },
126
+ cookieSigner
127
+ );
128
+ }
129
+ }
130
+ if (result.error) {
131
+ return res.status(result.status).json(result.error);
132
+ }
133
+ res.status(result.status).end();
134
+ }
135
+
136
+ // src/handlers/finishLogin.ts
137
+ import { finishLoginHandler } from "@seamless-auth/core/handlers/finishLogin";
138
+
139
+ // src/internal/buildAuthorization.ts
140
+ import { createServiceToken } from "@seamless-auth/core";
141
+ function buildServiceAuthorization(req) {
142
+ if (!req.cookiePayload?.sub && !req.user.sub) {
143
+ return void 0;
144
+ }
145
+ const token = createServiceToken({
146
+ subject: req.cookiePayload?.sub || req.user.sub,
147
+ issuer: process.env.APP_ORIGIN,
148
+ audience: process.env.AUTH_SERVER_URL,
149
+ serviceSecret: process.env.API_SERVICE_TOKEN,
150
+ keyId: "dev-main"
151
+ });
152
+ return `Bearer ${token}`;
153
+ }
154
+
155
+ // src/handlers/finishLogin.ts
156
+ async function finishLogin(req, res, opts) {
157
+ const cookieSigner = {
158
+ secret: opts.cookieSecret,
159
+ secure: process.env.NODE_ENV === "production",
160
+ sameSite: process.env.NODE_ENV === "production" ? "none" : "lax"
161
+ };
162
+ const authorization = buildServiceAuthorization(req);
163
+ const result = await finishLoginHandler(
164
+ { body: req.body, authorization },
165
+ {
166
+ authServerUrl: opts.authServerUrl,
167
+ cookieDomain: opts.cookieDomain,
168
+ accessCookieName: opts.accessCookieName,
169
+ refreshCookieName: opts.refreshCookieName
170
+ }
171
+ );
172
+ if (!cookieSigner.secret) {
173
+ throw new Error("Missing COOKIE_SIGNING_KEY");
174
+ }
175
+ if (result.setCookies) {
176
+ for (const c of result.setCookies) {
177
+ setSessionCookie(
178
+ res,
179
+ {
180
+ name: c.name,
181
+ payload: c.value,
182
+ domain: c.domain,
183
+ ttlSeconds: c.ttl
184
+ },
185
+ cookieSigner
186
+ );
187
+ }
188
+ }
189
+ if (result.error) {
190
+ return res.status(result.status).json(result.error);
191
+ }
192
+ res.status(result.status).json(result.body).end();
193
+ }
194
+
195
+ // src/handlers/register.ts
196
+ import { registerHandler } from "@seamless-auth/core/handlers/register";
197
+ async function register(req, res, opts) {
198
+ const cookieSigner = {
199
+ secret: opts.cookieSecret,
200
+ secure: process.env.NODE_ENV === "production",
201
+ sameSite: process.env.NODE_ENV === "production" ? "none" : "lax"
202
+ };
203
+ const result = await registerHandler(
204
+ { body: req.body },
205
+ {
206
+ authServerUrl: opts.authServerUrl,
207
+ cookieDomain: opts.cookieDomain,
208
+ registrationCookieName: opts.registrationCookieName
209
+ }
210
+ );
211
+ if (!cookieSigner.secret) {
212
+ throw new Error("Missing COOKIE_SIGNING_KEY");
213
+ }
214
+ if (result.setCookies) {
215
+ for (const c of result.setCookies) {
216
+ setSessionCookie(
217
+ res,
218
+ {
219
+ name: opts.registrationCookieName || "seamless-auth-registraion",
220
+ payload: c.value,
221
+ domain: c.domain,
222
+ ttlSeconds: c.ttl
223
+ },
224
+ cookieSigner
225
+ );
226
+ }
227
+ }
228
+ if (result.error) {
229
+ return res.status(result.status).json(result.error);
230
+ }
231
+ res.status(result.status).json(result.body).end();
232
+ }
233
+
234
+ // src/handlers/finishRegister.ts
235
+ import { finishRegisterHandler } from "@seamless-auth/core/handlers/finishRegister";
236
+ async function finishRegister(req, res, opts) {
237
+ const cookieSigner = {
238
+ secret: opts.cookieSecret,
239
+ secure: process.env.NODE_ENV === "production",
240
+ sameSite: process.env.NODE_ENV === "production" ? "none" : "lax"
241
+ };
242
+ const authorization = buildServiceAuthorization(req);
243
+ const result = await finishRegisterHandler(
244
+ { body: req.body, authorization },
245
+ {
246
+ authServerUrl: opts.authServerUrl,
247
+ cookieDomain: opts.cookieDomain,
248
+ accessCookieName: opts.accessCookieName,
249
+ refreshCookieName: opts.refreshCookieName
250
+ }
251
+ );
252
+ if (!cookieSigner.secret) {
253
+ throw new Error("Missing COOKIE_SIGNING_KEY");
254
+ }
255
+ if (result.setCookies) {
256
+ for (const c of result.setCookies) {
257
+ setSessionCookie(
258
+ res,
259
+ {
260
+ name: c.name,
261
+ payload: c.value,
262
+ domain: c.domain,
263
+ ttlSeconds: c.ttl
264
+ },
265
+ cookieSigner
266
+ );
267
+ }
268
+ }
269
+ if (result.error) {
270
+ return res.status(result.status).json(result.error);
271
+ }
272
+ res.status(result.status).end();
273
+ }
274
+
275
+ // src/handlers/me.ts
276
+ import { meHandler } from "@seamless-auth/core/handlers/me";
277
+ async function me(req, res, opts) {
278
+ const authorization = buildServiceAuthorization(req);
279
+ const result = await meHandler({
280
+ authServerUrl: opts.authServerUrl,
281
+ preAuthCookieName: opts.preAuthCookieName,
282
+ authorization
283
+ });
284
+ if (result.clearCookies) {
285
+ for (const name of result.clearCookies) {
286
+ clearSessionCookie(res, opts.cookieDomain || "", name);
287
+ }
288
+ }
289
+ if (result.error) {
290
+ return res.status(result.status).json({ error: result.error });
291
+ }
292
+ res.status(result.status).json(result.body);
293
+ }
294
+
295
+ // src/handlers/logout.ts
296
+ import { logoutHandler } from "@seamless-auth/core/handlers/logout";
297
+ async function logout(req, res, opts) {
298
+ const result = await logoutHandler({
299
+ authServerUrl: opts.authServerUrl,
300
+ accessCookieName: opts.accessCookieName,
301
+ registrationCookieName: opts.registrationCookieName,
302
+ refreshCookieName: opts.refreshCookieName
303
+ });
304
+ clearAllCookies(res, opts.cookieDomain || "", ...result.clearCookies);
305
+ res.status(result.status).end();
306
+ }
307
+
308
+ // src/createServer.ts
309
+ import {
310
+ authFetch
311
+ } from "@seamless-auth/core";
312
+ function createSeamlessAuthServer(opts) {
313
+ const r = express.Router();
314
+ r.use(express.json());
315
+ r.use(cookieParser());
316
+ const resolvedOpts = {
317
+ authServerUrl: opts.authServerUrl,
318
+ cookieSecret: opts.cookieSecret,
319
+ serviceSecret: opts.serviceSecret,
320
+ jwksKid: opts.jwksKid ?? "dev-main",
321
+ cookieDomain: opts.cookieDomain ?? "",
322
+ accessCookieName: opts.accessCookieName ?? "seamless-access",
323
+ registrationCookieName: opts.registrationCookieName ?? "seamless-ephemeral",
324
+ refreshCookieName: opts.refreshCookieName ?? "seamless-refresh",
325
+ preAuthCookieName: opts.preAuthCookieName ?? "seamless-ephemeral"
326
+ };
327
+ const proxyWithIdentity = (path, identity, method = "POST") => async (req, res) => {
328
+ if (!req.cookiePayload?.sub) {
329
+ res.status(401).json({ error: "unauthenticated" });
330
+ return;
331
+ }
332
+ if (identity === "access" && !req.cookies[resolvedOpts.accessCookieName]) {
333
+ res.status(401).json({ error: "access session required" });
334
+ return;
335
+ }
336
+ if (identity === "preAuth" && !req.cookies[resolvedOpts.preAuthCookieName]) {
337
+ res.status(401).json({ error: "pre-auth session required" });
338
+ return;
339
+ }
340
+ if (identity === "register" && !req.cookies[resolvedOpts.registrationCookieName]) {
341
+ res.status(401).json({ error: "registeration session required" });
342
+ return;
343
+ }
344
+ const authorization = buildServiceAuthorization(req);
345
+ const upstream = await authFetch(
346
+ `${resolvedOpts.authServerUrl}/${path}`,
347
+ {
348
+ method,
349
+ body: req.body,
350
+ authorization
351
+ }
352
+ );
353
+ const data = await upstream.json();
354
+ res.status(upstream.status).json(data);
355
+ };
356
+ r.use(
357
+ createEnsureCookiesMiddleware({
358
+ authServerUrl: resolvedOpts.authServerUrl,
359
+ cookieDomain: resolvedOpts.cookieDomain,
360
+ accessCookieName: resolvedOpts.accessCookieName,
361
+ registrationCookieName: resolvedOpts.registrationCookieName,
362
+ refreshCookieName: resolvedOpts.refreshCookieName,
363
+ preAuthCookieName: resolvedOpts.preAuthCookieName,
364
+ cookieSecret: resolvedOpts.cookieSecret,
365
+ serviceSecret: resolvedOpts.serviceSecret,
366
+ issuer: process.env.APP_ORIGIN,
367
+ audience: resolvedOpts.authServerUrl,
368
+ keyId: resolvedOpts.jwksKid
369
+ })
370
+ );
371
+ r.post(
372
+ "/webAuthn/login/start",
373
+ proxyWithIdentity("webAuthn/login/start", "preAuth")
374
+ );
375
+ r.post(
376
+ "/webAuthn/login/finish",
377
+ (req, res) => finishLogin(req, res, resolvedOpts)
378
+ );
379
+ r.get(
380
+ "/webAuthn/register/start",
381
+ proxyWithIdentity("webAuthn/register/start", "preAuth", "GET")
382
+ );
383
+ r.post(
384
+ "/webAuthn/register/finish",
385
+ (req, res) => finishRegister(req, res, resolvedOpts)
386
+ );
387
+ r.post(
388
+ "/otp/verify-phone-otp",
389
+ proxyWithIdentity("otp/verify-phone-otp", "preAuth")
390
+ );
391
+ r.post(
392
+ "/otp/verify-email-otp",
393
+ proxyWithIdentity("otp/verify-email-otp", "preAuth")
394
+ );
395
+ r.post("/login", (req, res) => login(req, res, resolvedOpts));
396
+ r.post(
397
+ "/registration/register",
398
+ (req, res) => register(req, res, resolvedOpts)
399
+ );
400
+ r.get("/users/me", (req, res) => me(req, res, resolvedOpts));
401
+ r.get("/logout", (req, res) => logout(req, res, resolvedOpts));
402
+ r.post("/users/update", proxyWithIdentity("users/update", "access"));
403
+ r.post(
404
+ "/users/credentials",
405
+ proxyWithIdentity("users/credentials", "access")
406
+ );
407
+ r.delete(
408
+ "/users/credentials",
409
+ proxyWithIdentity("users/credentials", "access")
410
+ );
411
+ return r;
412
+ }
413
+
414
+ // src/middleware/requireAuth.ts
415
+ import { verifyCookieJwt } from "@seamless-auth/core";
416
+ function requireAuth(opts) {
417
+ const { cookieName = "seamless-access", cookieSecret } = opts;
418
+ if (!cookieSecret) {
419
+ throw new Error("requireAuth: missing cookieSecret");
420
+ }
421
+ return function(req, res, next) {
422
+ const token = req.cookies?.[cookieName];
423
+ if (!token) {
424
+ res.status(401).json({
425
+ error: "Authentication required"
426
+ });
427
+ return;
428
+ }
429
+ const payload = verifyCookieJwt(token, cookieSecret);
430
+ if (!payload || !payload.sub) {
431
+ res.status(401).json({
432
+ error: "Invalid or expired session"
433
+ });
434
+ return;
435
+ }
436
+ const user = {
437
+ sub: payload.sub,
438
+ roles: Array.isArray(payload.roles) ? payload.roles : [],
439
+ email: payload.email,
440
+ phone: payload.phone,
441
+ iat: payload.iat,
442
+ exp: payload.exp
443
+ };
444
+ req.user = user;
445
+ next();
446
+ };
447
+ }
448
+
449
+ // src/middleware/requireRole.ts
450
+ function requireRole(requiredRoles) {
451
+ const roles = Array.isArray(requiredRoles) ? requiredRoles : [requiredRoles];
452
+ return (req, res, next) => {
453
+ const user = req.user;
454
+ if (!user) {
455
+ res.status(401).json({
456
+ error: "Authentication required"
457
+ });
458
+ return;
459
+ }
460
+ if (!Array.isArray(user.roles)) {
461
+ res.status(403).json({
462
+ error: "User has no roles assigned"
463
+ });
464
+ return;
465
+ }
466
+ const hasRole = roles.some((role) => user.roles.includes(role));
467
+ if (!hasRole) {
468
+ res.status(403).json({
469
+ error: "Insufficient role",
470
+ required: roles,
471
+ actual: user.roles
472
+ });
473
+ return;
474
+ }
475
+ next();
476
+ };
477
+ }
478
+
479
+ // src/getSeamlessUser.ts
480
+ import {
481
+ getSeamlessUser as getSeamlessUserCore
482
+ } from "@seamless-auth/core";
483
+ async function getSeamlessUser(req, opts) {
484
+ const authorization = buildServiceAuthorization(req);
485
+ return getSeamlessUserCore(req.cookies ?? {}, {
486
+ authServerUrl: opts.authServerUrl,
487
+ cookieSecret: opts.cookieSecret,
488
+ cookieName: opts.cookieName ?? "seamless-access",
489
+ authorization
490
+ });
491
+ }
492
+
493
+ // src/index.ts
494
+ var index_default = createSeamlessAuthServer;
495
+ export {
496
+ createEnsureCookiesMiddleware,
497
+ index_default as default,
498
+ getSeamlessUser,
499
+ requireAuth,
500
+ requireRole
501
+ };
package/package.json CHANGED
@@ -1,37 +1,54 @@
1
1
  {
2
2
  "name": "@seamless-auth/express",
3
- "version": "0.0.2-beta.1",
3
+ "version": "0.0.2-beta.11",
4
4
  "description": "Express adapter for Seamless Auth passwordless authentication",
5
- "license": "MIT",
5
+ "license": "AGPL-3.0-only",
6
6
  "type": "module",
7
7
  "main": "dist/index.js",
8
8
  "types": "./dist/index.d.ts",
9
9
  "author": "Fells Code LLC",
10
+ "files": [
11
+ "dist",
12
+ "LICENSE",
13
+ "LICENSE.md",
14
+ "README.md"
15
+ ],
16
+ "exports": {
17
+ ".": {
18
+ "types": "./dist/index.d.ts",
19
+ "import": "./dist/index.js"
20
+ }
21
+ },
22
+ "engines": {
23
+ "node": ">=18"
24
+ },
10
25
  "scripts": {
11
- "build": "tsc -p tsconfig.json && node build.mjs",
12
- "dev": "tsc --watch"
26
+ "build": "tsup src/index.ts --format esm --out-dir dist --dts --splitting",
27
+ "dev": "tsc --watch",
28
+ "test": "npm run build && NODE_OPTIONS=--experimental-vm-modules jest",
29
+ "test:watch": "npm run build && NODE_OPTIONS=--experimental-vm-modules jest --watch"
13
30
  },
14
31
  "repository": {
15
32
  "type": "git",
16
- "url": "git+https://github.com/fells-code/seamless-auth-server.git"
33
+ "url": "https://github.com/fells-code/seamless-auth-server/tree/main/packages/express"
17
34
  },
18
- "files": [
19
- "dist"
20
- ],
21
35
  "peerDependencies": {
22
- "@types/express": ">=5.0.0",
23
- "express": ">=5.1.0"
36
+ "express": ">=4.18.0",
37
+ "@types/express": ">=4.17.0"
24
38
  },
25
39
  "dependencies": {
40
+ "@seamless-auth/core": "beta",
26
41
  "cookie-parser": "^1.4.6",
27
- "dotenv": "^17.2.3",
28
- "jose": "^6.1.1",
29
- "jsonwebtoken": "^9.0.2",
30
- "node-fetch": "^3.3.2"
42
+ "jsonwebtoken": "^9.0.3"
31
43
  },
32
44
  "devDependencies": {
33
45
  "@types/cookie-parser": "^1.4.10",
46
+ "@types/jest": "^29.5.14",
34
47
  "@types/jsonwebtoken": "^9.0.10",
48
+ "jest": "^29.7.0",
49
+ "ts-node": "^10.9.2",
50
+ "supertest": "^7.2.2",
51
+ "tsup": "^8.5.1",
35
52
  "typescript": "^5.5.0"
36
53
  },
37
54
  "publishConfig": {
@@ -1,48 +0,0 @@
1
- import { Router } from "express";
2
- import type { SeamlessAuthServerOptions } from "./types";
3
- /**
4
- * Creates an Express Router that proxies all authentication traffic to a Seamless Auth server.
5
- *
6
- * This helper wires your API backend to a Seamless Auth instance running in
7
- * "server mode." It automatically forwards login, registration, WebAuthn,
8
- * logout, token refresh, and session validation routes to the auth server
9
- * and handles all cookie management required for a seamless login flow.
10
- *
11
- * ### Responsibilities
12
- * - Proxies all `/auth/*` routes to the upstream Seamless Auth server
13
- * - Manages `access`, `registration`, `pre-auth`, and `refresh` cookies
14
- * - Normalizes cookie settings for cross-domain or same-domain deployments
15
- * - Ensures authentication routes behave consistently across environments
16
- * - Provides shared middleware for auth flows
17
- *
18
- * ### Cookie Types
19
- * - **accessCookie** – long-lived session cookie for authenticated API requests
20
- * - **registrationCookie** – ephemeral cookie used during registration and OTP/WebAuthn flows
21
- * - **preAuthCookie** – short-lived cookie used during login initiation
22
- * - **refreshCookie** – opaque refresh token cookie used to rotate session tokens
23
- *
24
- * All cookie names and their domains may be customized via the `opts` parameter.
25
- *
26
- * ### Example
27
- * ```ts
28
- * app.use("/auth", createSeamlessAuthServer({
29
- * authServerUrl: "https://identifier.seamlessauth.com",
30
- * cookieDomain: "mycompany.com",
31
- * accesscookieName: "sa_access",
32
- * registrationCookieName: "sa_registration",
33
- * refreshCookieName: "sa_refresh",
34
- * }));
35
- * ```
36
- *
37
- * @param opts - Configuration options for the Seamless Auth proxy:
38
- * - `authServerUrl` — Base URL of your Seamless Auth instance (required)
39
- * - `cookieDomain` — Domain attribute applied to all auth cookies
40
- * - `accesscookieName` — Name of the session access cookie
41
- * - `registrationCookieName` — Name of the ephemeral registration cookie
42
- * - `refreshCookieName` — Name of the refresh token cookie
43
- * - `preAuthCookieName` — Name of the cookie used during login initiation
44
- *
45
- * @returns An Express `Router` preconfigured with all Seamless Auth routes.
46
- */
47
- export declare function createSeamlessAuthServer(opts: SeamlessAuthServerOptions): Router;
48
- //# sourceMappingURL=createServer.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"createServer.d.ts","sourceRoot":"","sources":["../src/createServer.ts"],"names":[],"mappings":"AAAA,OAAgB,EAAqB,MAAM,EAAE,MAAM,SAAS,CAAC;AAQ7D,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,SAAS,CAAC;AAIzD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,yBAAyB,GAC9B,MAAM,CA0LR"}