@seamless-auth/express 0.0.4-beta.0 → 0.1.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.
package/README.md CHANGED
@@ -110,14 +110,17 @@ This keeps trust boundaries clean and auditable.
110
110
 
111
111
  ## Environment Variables
112
112
 
113
- | Variable | Description | Example |
114
- | -------------------- | ----------------------------------------- | ------------------------------------------------------ |
115
- | `AUTH_SERVER_URL` | Base URL of your Seamless Auth Server | `https://auth.client.com` |
116
- | `COOKIE_SIGNING_KEY` | Secret for signing API session cookies | `local-dev-secret` |
117
- | `API_SERVICE_TOKEN` | API → Auth Server service secret | `shared-m2m-value` |
118
- | `APP_ORIGIN` | Your site URL (or localhost in demo mode) | `https://myapp.com` |
119
- | `DATABASE_URL` | Database URL for your API | `postgres://myuser:mypassword@localhost:5432/seamless` |
120
- | `DB_NAME` | Name of your database | `seamless` |
113
+ | Variable | Description | Example |
114
+ | -------------------- | ----------------------------------------- | ------------------------- |
115
+ | `AUTH_SERVER_URL` | Base URL of your Seamless Auth Server | `https://auth.client.com` |
116
+ | `COOKIE_SIGNING_KEY` | Secret for signing API session cookies | `local-dev-secret` |
117
+ | `API_SERVICE_TOKEN` | API → Auth Server service secret | `shared-m2m-value` |
118
+ | `APP_ORIGIN` | Your site URL (or localhost in demo mode) | `https://myapp.com` |
119
+ | `DB_HOST` | Database Host | `localhost` |
120
+ | `DB_PORT` | Database Port | `5432` |
121
+ | `DB_USER` | Database user | `myuser` |
122
+ | `DB_PASSWORD` | Database password | `mypassword` |
123
+ | `DB_NAME` | Name of your database | `seamless` |
121
124
 
122
125
  ---
123
126
 
@@ -219,7 +222,7 @@ Returned shape (example):
219
222
  AUTH_SERVER_URL=http://localhost:5312
220
223
  SEAMLESS_SERVICE_TOKEN=generated-secret
221
224
  COOKIE_SIGNING_KEY=local-dev-key
222
- FRONTEND_URL=https://localhost:5001
225
+ FRONTEND_URL=http://localhost:5001
223
226
  ```
224
227
 
225
228
  ---
package/dist/index.d.ts CHANGED
@@ -1,15 +1,27 @@
1
1
  import { Router, Request, Response, NextFunction, RequestHandler } from 'express';
2
- import { JwtPayload } from 'jsonwebtoken';
3
2
 
4
- interface SeamlessAuthServerOptions {
3
+ type SeamlessAuthServerOptions = {
5
4
  authServerUrl: string;
5
+ cookieSecret: string;
6
+ serviceSecret: string;
7
+ issuer: string;
8
+ audience: string;
9
+ jwksKid?: string;
6
10
  cookieDomain?: string;
7
11
  accessCookieName?: string;
8
12
  registrationCookieName?: string;
9
13
  refreshCookieName?: string;
10
14
  preAuthCookieName?: string;
15
+ };
16
+ interface SeamlessAuthUser {
17
+ id: string;
18
+ sub: string;
19
+ roles: string[];
20
+ email: string;
21
+ phone: string;
22
+ iat?: number;
23
+ exp?: number;
11
24
  }
12
-
13
25
  /**
14
26
  * Creates an Express Router that proxies all authentication traffic to a Seamless Auth server.
15
27
  *
@@ -38,6 +50,9 @@ interface SeamlessAuthServerOptions {
38
50
  * app.use("/auth", createSeamlessAuthServer({
39
51
  * authServerUrl: "https://identifier.seamlessauth.com",
40
52
  * cookieDomain: "mycompany.com",
53
+ * cookieSecret: "someLongRandomValue"
54
+ * serviceSecret: "someLongRandomValueToo"
55
+ * jwksKid: "dev-main"
41
56
  * accessCookieName: "sa_access",
42
57
  * registrationCookieName: "sa_registration",
43
58
  * refreshCookieName: "sa_refresh",
@@ -46,6 +61,9 @@ interface SeamlessAuthServerOptions {
46
61
  *
47
62
  * @param opts - Configuration options for the Seamless Auth proxy:
48
63
  * - `authServerUrl` — Base URL of your Seamless Auth instance (required)
64
+ * - `cookieSecret` — The value to encode your cookies secrets with (required)
65
+ * - `serviceSecret` - An machine to machine shared secret that matches your auth servers (required)
66
+ * - `jwksKid` - The active jwks KID
49
67
  * - `cookieDomain` — Domain attribute applied to all auth cookies
50
68
  * - `accessCookieName` — Name of the session access cookie
51
69
  * - `registrationCookieName` — Name of the ephemeral registration cookie
@@ -56,6 +74,10 @@ interface SeamlessAuthServerOptions {
56
74
  */
57
75
  declare function createSeamlessAuthServer(opts: SeamlessAuthServerOptions): Router;
58
76
 
77
+ interface RequireAuthOptions {
78
+ cookieName?: string;
79
+ cookieSecret: string;
80
+ }
59
81
  /**
60
82
  * Express middleware that enforces authentication using Seamless Auth cookies.
61
83
  *
@@ -106,9 +128,6 @@ declare function createSeamlessAuthServer(opts: SeamlessAuthServerOptions): Rout
106
128
  * @returns An Express middleware function that enforces Seamless Auth
107
129
  * authentication on incoming requests.
108
130
  */
109
- interface AuthenticatedRequest extends Request {
110
- user?: JwtPayload;
111
- }
112
131
  interface RequireAuthOptions {
113
132
  cookieName?: string;
114
133
  cookieSecret: string;
@@ -121,32 +140,22 @@ interface RequireAuthOptions {
121
140
  * - This middleware does NOT attempt token refresh.
122
141
  * - Refresh is handled upstream by ensureCookies().
123
142
  */
124
- declare function requireAuth(opts: RequireAuthOptions): (req: AuthenticatedRequest, res: Response, next: NextFunction) => void;
143
+ declare function requireAuth(opts: RequireAuthOptions): (req: Request, res: Response, next: NextFunction) => void;
125
144
 
126
145
  /**
127
- * Express middleware that enforces role-based authorization for Seamless Auth sessions.
146
+ * Express middleware that enforces role-based authorization for Seamless Auth.
128
147
  *
129
- * This guard assumes that `requireAuth()` has already validated the request
130
- * and populated `req.user` with the decoded Seamless Auth session payload.
131
- * It then checks whether the user’s roles include the required role (or any
132
- * of several, when an array is provided).
148
+ * This middleware assumes `requireAuth()` has already:
149
+ * - authenticated the request
150
+ * - populated `req.user` with the authenticated session payload
133
151
  *
134
- * If the user possesses the required authorization, the request proceeds.
135
- * Otherwise, the middleware responds with a 403 Forbidden error.
152
+ * `requireRole` performs **authorization only**. It does not inspect cookies,
153
+ * verify tokens, or read environment variables.
136
154
  *
137
- * ### Responsibilities
138
- * - Validates that `req.user` is present (enforced upstream by `requireAuth`)
139
- * - Ensures the authenticated user includes the specified role(s)
140
- * - Blocks unauthorized access with a standardized JSON 403 response
155
+ * If any of the required roles are present on the user, access is granted.
156
+ * Otherwise, a 403 Forbidden response is returned.
141
157
  *
142
- * ### Parameters
143
- * - **requiredRole** — A role (string) or list of roles the user must have.
144
- * If an array is provided, *any* matching role grants access.
145
- * - **cookieName** — Optional name of the access cookie to inspect.
146
- * Defaults to `"seamless-access"`, but typically not needed because
147
- * `requireAuth` is expected to run first.
148
- *
149
- * ### Example
158
+ * * ### Example
150
159
  * ```ts
151
160
  * // Require a single role
152
161
  * app.get("/admin/users",
@@ -163,13 +172,10 @@ declare function requireAuth(opts: RequireAuthOptions): (req: AuthenticatedReque
163
172
  * requireRole(["admin", "supervisor"]),
164
173
  * updateSettingsHandler
165
174
  * );
166
- * ```
167
175
  *
168
- * @param requiredRole - A role or list of roles required to access the route.
169
- * @param cookieName - Optional access cookie name (defaults to `seamless-access`).
170
- * @returns An Express middleware function enforcing role-based access control.
176
+ * @param requiredRoles - A role or list of roles required to access the route
171
177
  */
172
- declare function requireRole(role: string, cookieName?: string): RequestHandler;
178
+ declare function requireRole(requiredRoles: string | string[]): RequestHandler;
173
179
 
174
180
  interface EnsureCookiesMiddlewareOptions {
175
181
  authServerUrl: string;
@@ -184,10 +190,8 @@ interface EnsureCookiesMiddlewareOptions {
184
190
  audience: string;
185
191
  keyId: string;
186
192
  }
187
- declare function createEnsureCookiesMiddleware(opts: EnsureCookiesMiddlewareOptions): (req: Request & {
188
- cookiePayload?: any;
189
- }, res: Response, next: NextFunction) => Promise<void>;
193
+ declare function createEnsureCookiesMiddleware(opts: EnsureCookiesMiddlewareOptions): (req: Request, res: Response, next: NextFunction) => Promise<void>;
190
194
 
191
- declare function getSeamlessUser<T = any>(req: Request, authServerUrl: string, cookieName?: string): Promise<T | null>;
195
+ declare function getSeamlessUser(req: Request, opts: SeamlessAuthServerOptions): Promise<any>;
192
196
 
193
- export { type SeamlessAuthServerOptions, createEnsureCookiesMiddleware, createSeamlessAuthServer as default, getSeamlessUser, requireAuth, requireRole };
197
+ export { type SeamlessAuthServerOptions, type SeamlessAuthUser, createEnsureCookiesMiddleware, createSeamlessAuthServer as default, getSeamlessUser, requireAuth, requireRole };
package/dist/index.js CHANGED
@@ -98,7 +98,7 @@ function applyResult(res, req, result, opts, cookieSigner) {
98
98
  import { loginHandler } from "@seamless-auth/core/handlers/login";
99
99
  async function login(req, res, opts) {
100
100
  const cookieSigner = {
101
- secret: process.env.COOKIE_SIGNING_KEY,
101
+ secret: opts.cookieSecret,
102
102
  secure: process.env.NODE_ENV === "production",
103
103
  sameSite: process.env.NODE_ENV === "production" ? "none" : "lax"
104
104
  };
@@ -138,16 +138,16 @@ import { finishLoginHandler } from "@seamless-auth/core/handlers/finishLogin";
138
138
 
139
139
  // src/internal/buildAuthorization.ts
140
140
  import { createServiceToken } from "@seamless-auth/core";
141
- function buildServiceAuthorization(req) {
142
- if (!req.cookiePayload?.sub) {
141
+ function buildServiceAuthorization(req, opts) {
142
+ if (!req.cookiePayload?.sub && !req.user.sub) {
143
143
  return void 0;
144
144
  }
145
145
  const token = createServiceToken({
146
- subject: req.cookiePayload.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"
146
+ subject: req.cookiePayload?.sub || req.user.sub,
147
+ issuer: opts.issuer,
148
+ audience: opts.audience,
149
+ serviceSecret: opts.serviceSecret,
150
+ keyId: opts.jwksKid || "dev-main"
151
151
  });
152
152
  return `Bearer ${token}`;
153
153
  }
@@ -155,11 +155,11 @@ function buildServiceAuthorization(req) {
155
155
  // src/handlers/finishLogin.ts
156
156
  async function finishLogin(req, res, opts) {
157
157
  const cookieSigner = {
158
- secret: process.env.COOKIE_SIGNING_KEY,
158
+ secret: opts.cookieSecret,
159
159
  secure: process.env.NODE_ENV === "production",
160
160
  sameSite: process.env.NODE_ENV === "production" ? "none" : "lax"
161
161
  };
162
- const authorization = buildServiceAuthorization(req);
162
+ const authorization = buildServiceAuthorization(req, opts);
163
163
  const result = await finishLoginHandler(
164
164
  { body: req.body, authorization },
165
165
  {
@@ -196,7 +196,7 @@ async function finishLogin(req, res, opts) {
196
196
  import { registerHandler } from "@seamless-auth/core/handlers/register";
197
197
  async function register(req, res, opts) {
198
198
  const cookieSigner = {
199
- secret: process.env.COOKIE_SIGNING_KEY,
199
+ secret: opts.cookieSecret,
200
200
  secure: process.env.NODE_ENV === "production",
201
201
  sameSite: process.env.NODE_ENV === "production" ? "none" : "lax"
202
202
  };
@@ -235,11 +235,11 @@ async function register(req, res, opts) {
235
235
  import { finishRegisterHandler } from "@seamless-auth/core/handlers/finishRegister";
236
236
  async function finishRegister(req, res, opts) {
237
237
  const cookieSigner = {
238
- secret: process.env.COOKIE_SIGNING_KEY,
238
+ secret: opts.cookieSecret,
239
239
  secure: process.env.NODE_ENV === "production",
240
240
  sameSite: process.env.NODE_ENV === "production" ? "none" : "lax"
241
241
  };
242
- const authorization = buildServiceAuthorization(req);
242
+ const authorization = buildServiceAuthorization(req, opts);
243
243
  const result = await finishRegisterHandler(
244
244
  { body: req.body, authorization },
245
245
  {
@@ -269,13 +269,13 @@ async function finishRegister(req, res, opts) {
269
269
  if (result.error) {
270
270
  return res.status(result.status).json(result.error);
271
271
  }
272
- res.status(result.status).end();
272
+ res.status(result.status).json({ message: "success" });
273
273
  }
274
274
 
275
275
  // src/handlers/me.ts
276
276
  import { meHandler } from "@seamless-auth/core/handlers/me";
277
277
  async function me(req, res, opts) {
278
- const authorization = buildServiceAuthorization(req);
278
+ const authorization = buildServiceAuthorization(req, opts);
279
279
  const result = await meHandler({
280
280
  authServerUrl: opts.authServerUrl,
281
281
  preAuthCookieName: opts.preAuthCookieName,
@@ -305,10 +305,50 @@ async function logout(req, res, opts) {
305
305
  res.status(result.status).end();
306
306
  }
307
307
 
308
+ // src/handlers/pollMagicLinkConfirmation.ts
309
+ import { pollMagicLinkConfirmationHandler } from "@seamless-auth/core/handlers/pollMagicLinkConfirmationHandler";
310
+ async function pollMagicLinkConfirmation(req, res, opts) {
311
+ const cookieSigner = {
312
+ secret: opts.cookieSecret,
313
+ secure: process.env.NODE_ENV === "production",
314
+ sameSite: process.env.NODE_ENV === "production" ? "none" : "lax"
315
+ };
316
+ const authorization = buildServiceAuthorization(req, opts);
317
+ const result = await pollMagicLinkConfirmationHandler(
318
+ { authorization },
319
+ {
320
+ authServerUrl: opts.authServerUrl,
321
+ cookieDomain: opts.cookieDomain,
322
+ accessCookieName: opts.accessCookieName,
323
+ refreshCookieName: opts.refreshCookieName
324
+ }
325
+ );
326
+ if (!cookieSigner.secret) {
327
+ throw new Error("Missing COOKIE_SIGNING_KEY");
328
+ }
329
+ if (result.setCookies) {
330
+ for (const c of result.setCookies) {
331
+ setSessionCookie(
332
+ res,
333
+ {
334
+ name: c.name,
335
+ payload: c.value,
336
+ domain: c.domain,
337
+ ttlSeconds: c.ttl
338
+ },
339
+ cookieSigner
340
+ );
341
+ }
342
+ }
343
+ if (result.error) {
344
+ return res.status(result.status).json(result.error);
345
+ }
346
+ res.status(result.status).json(result.body).end();
347
+ }
348
+
308
349
  // src/createServer.ts
309
350
  import {
310
- authFetch,
311
- createServiceToken as createServiceToken2
351
+ authFetch
312
352
  } from "@seamless-auth/core";
313
353
  function createSeamlessAuthServer(opts) {
314
354
  const r = express.Router();
@@ -316,6 +356,11 @@ function createSeamlessAuthServer(opts) {
316
356
  r.use(cookieParser());
317
357
  const resolvedOpts = {
318
358
  authServerUrl: opts.authServerUrl,
359
+ issuer: opts.issuer,
360
+ audience: opts.audience,
361
+ cookieSecret: opts.cookieSecret,
362
+ serviceSecret: opts.serviceSecret,
363
+ jwksKid: opts.jwksKid ?? "dev-main",
319
364
  cookieDomain: opts.cookieDomain ?? "",
320
365
  accessCookieName: opts.accessCookieName ?? "seamless-access",
321
366
  registrationCookieName: opts.registrationCookieName ?? "seamless-ephemeral",
@@ -339,14 +384,11 @@ function createSeamlessAuthServer(opts) {
339
384
  res.status(401).json({ error: "registeration session required" });
340
385
  return;
341
386
  }
342
- const authorization = buildServiceAuthorization2(req);
387
+ const authorization = buildServiceAuthorization(req, resolvedOpts);
388
+ const options = method == "GET" ? { method, authorization } : { method, authorization, body: req.body };
343
389
  const upstream = await authFetch(
344
390
  `${resolvedOpts.authServerUrl}/${path}`,
345
- {
346
- method,
347
- body: req.body,
348
- authorization
349
- }
391
+ options
350
392
  );
351
393
  const data = await upstream.json();
352
394
  res.status(upstream.status).json(data);
@@ -359,26 +401,13 @@ function createSeamlessAuthServer(opts) {
359
401
  registrationCookieName: resolvedOpts.registrationCookieName,
360
402
  refreshCookieName: resolvedOpts.refreshCookieName,
361
403
  preAuthCookieName: resolvedOpts.preAuthCookieName,
362
- cookieSecret: process.env.COOKIE_SIGNING_KEY,
363
- serviceSecret: process.env.API_SERVICE_TOKEN,
364
- issuer: process.env.APP_ORIGIN,
365
- audience: process.env.AUTH_SERVER_URL,
366
- keyId: "dev-main"
404
+ cookieSecret: resolvedOpts.cookieSecret,
405
+ serviceSecret: resolvedOpts.serviceSecret,
406
+ issuer: resolvedOpts.issuer,
407
+ audience: resolvedOpts.authServerUrl,
408
+ keyId: resolvedOpts.jwksKid
367
409
  })
368
410
  );
369
- function buildServiceAuthorization2(req) {
370
- if (!req.cookiePayload?.sub) {
371
- return void 0;
372
- }
373
- const token = createServiceToken2({
374
- subject: req.cookiePayload.sub,
375
- issuer: process.env.APP_ORIGIN,
376
- audience: process.env.AUTH_SERVER_URL,
377
- serviceSecret: process.env.API_SERVICE_TOKEN,
378
- keyId: "dev-main"
379
- });
380
- return `Bearer ${token}`;
381
- }
382
411
  r.post(
383
412
  "/webAuthn/login/start",
384
413
  proxyWithIdentity("webAuthn/login/start", "preAuth")
@@ -419,6 +448,19 @@ function createSeamlessAuthServer(opts) {
419
448
  "/users/credentials",
420
449
  proxyWithIdentity("users/credentials", "access")
421
450
  );
451
+ r.get("/magic-link", proxyWithIdentity("magic-link", "preAuth", "GET"));
452
+ r.get("/magic-link/verify/:token", async (req, res) => {
453
+ const upstream = await authFetch(
454
+ `${resolvedOpts.authServerUrl}/magic-link/verify/${req.params.token}`,
455
+ { method: "GET" }
456
+ );
457
+ const data = await upstream.json();
458
+ res.status(upstream.status).json(data);
459
+ });
460
+ r.get(
461
+ "/magic-link/check",
462
+ (req, res) => pollMagicLinkConfirmation(req, res, resolvedOpts)
463
+ );
422
464
  return r;
423
465
  }
424
466
 
@@ -432,58 +474,78 @@ function requireAuth(opts) {
432
474
  return function(req, res, next) {
433
475
  const token = req.cookies?.[cookieName];
434
476
  if (!token) {
435
- res.status(401).json({ error: "Missing access cookie" });
477
+ console.error(
478
+ "[SEAMLESS-AUTH-EXPRESS] - (requireAuth) - Missing expected cookie. Ensure you are using `cookieParser` in your express server",
479
+ cookieName
480
+ );
481
+ res.status(401).json({
482
+ error: "Failed to find authentication token required"
483
+ });
436
484
  return;
437
485
  }
438
486
  const payload = verifyCookieJwt(token, cookieSecret);
439
- if (!payload) {
440
- res.status(401).json({ error: "Invalid or expired access cookie" });
487
+ if (!payload || !payload.sub) {
488
+ res.status(401).json({
489
+ error: "Invalid or expired session"
490
+ });
441
491
  return;
442
492
  }
443
- req.user = payload;
493
+ const user = {
494
+ id: payload.sub,
495
+ sub: payload.sub,
496
+ // TODO: Silly to store the same value twice. Search every where its used and phase this out.
497
+ roles: Array.isArray(payload.roles) ? payload.roles : [],
498
+ email: payload.email,
499
+ phone: payload.phone,
500
+ iat: payload.iat,
501
+ exp: payload.exp
502
+ };
503
+ req.user = user;
444
504
  next();
445
505
  };
446
506
  }
447
507
 
448
508
  // src/middleware/requireRole.ts
449
- import jwt2 from "jsonwebtoken";
450
- function requireRole(role, cookieName = "seamless-access") {
509
+ function requireRole(requiredRoles) {
510
+ const roles = Array.isArray(requiredRoles) ? requiredRoles : [requiredRoles];
451
511
  return (req, res, next) => {
452
- try {
453
- const COOKIE_SECRET = process.env.COOKIE_SIGNING_KEY;
454
- if (!COOKIE_SECRET) {
455
- console.warn(
456
- "[SeamlessAuth] COOKIE_SIGNING_KEY missing \u2014 requireRole will always fail."
457
- );
458
- throw new Error("Missing required env COOKIE_SIGNING_KEY");
459
- }
460
- const token = req.cookies?.[cookieName];
461
- if (!token) {
462
- res.status(401).json({ error: "Missing access cookie" });
463
- return;
464
- }
465
- const payload = jwt2.verify(token, COOKIE_SECRET, {
466
- algorithms: ["HS256"]
512
+ const user = req.user;
513
+ if (!user) {
514
+ res.status(401).json({
515
+ error: "Authentication required"
467
516
  });
468
- if (!payload.roles?.includes(role)) {
469
- res.status(403).json({ error: `Forbidden: ${role} role required` });
470
- return;
471
- }
472
- next();
473
- } catch (err) {
474
- console.error(`[RequireRole] requireRole(${role}) failed:`, err.message);
475
- res.status(401).json({ error: "Invalid or expired access cookie" });
517
+ return;
518
+ }
519
+ if (!Array.isArray(user.roles)) {
520
+ res.status(403).json({
521
+ error: "User has no roles assigned"
522
+ });
523
+ return;
476
524
  }
525
+ const hasRole = roles.some((role) => user.roles.includes(role));
526
+ if (!hasRole) {
527
+ res.status(403).json({
528
+ error: "Insufficient role",
529
+ required: roles,
530
+ actual: user.roles
531
+ });
532
+ return;
533
+ }
534
+ next();
477
535
  };
478
536
  }
479
537
 
480
538
  // src/getSeamlessUser.ts
481
- import { getSeamlessUser as getSeamlessUserCore } from "@seamless-auth/core";
482
- async function getSeamlessUser(req, authServerUrl, cookieName = "seamless-access") {
539
+ import {
540
+ getSeamlessUser as getSeamlessUserCore
541
+ } from "@seamless-auth/core";
542
+ async function getSeamlessUser(req, opts) {
543
+ const authorization = buildServiceAuthorization(req, opts);
483
544
  return getSeamlessUserCore(req.cookies ?? {}, {
484
- authServerUrl,
485
- cookieSecret: process.env.COOKIE_SIGNING_KEY,
486
- cookieName
545
+ authServerUrl: opts.authServerUrl,
546
+ cookieSecret: opts.cookieSecret,
547
+ cookieName: opts.accessCookieName ?? "seamless-access",
548
+ authorization
487
549
  });
488
550
  }
489
551
 
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@seamless-auth/express",
3
- "version": "0.0.4-beta.0",
3
+ "version": "0.1.0",
4
4
  "description": "Express adapter for Seamless Auth passwordless authentication",
5
5
  "license": "AGPL-3.0-only",
6
6
  "type": "module",
7
7
  "main": "dist/index.js",
8
8
  "types": "./dist/index.d.ts",
9
- "author": "Fells Code LLC",
9
+ "author": "Fells Code, LLC",
10
10
  "files": [
11
11
  "dist",
12
12
  "LICENSE",
@@ -33,11 +33,11 @@
33
33
  "url": "https://github.com/fells-code/seamless-auth-server/tree/main/packages/express"
34
34
  },
35
35
  "peerDependencies": {
36
- "express": ">=4.18.0",
37
- "@types/express": ">=4.17.0"
36
+ "@types/express": ">=4.17.0",
37
+ "express": ">=4.18.0"
38
38
  },
39
39
  "dependencies": {
40
- "@seamless-auth/core": "^0.1.0",
40
+ "@seamless-auth/core": "^0.2.0",
41
41
  "cookie-parser": "^1.4.6",
42
42
  "jsonwebtoken": "^9.0.3"
43
43
  },
@@ -46,8 +46,8 @@
46
46
  "@types/jest": "^29.5.14",
47
47
  "@types/jsonwebtoken": "^9.0.10",
48
48
  "jest": "^29.7.0",
49
- "ts-node": "^10.9.2",
50
49
  "supertest": "^7.2.2",
50
+ "ts-node": "^10.9.2",
51
51
  "tsup": "^8.5.1",
52
52
  "typescript": "^5.5.0"
53
53
  },