@seamless-auth/express 0.0.1 → 0.0.2-beta.10

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 +99 -122
  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 -4
  8. package/dist/createServer.d.ts.map +0 -1
  9. package/dist/createServer.js +0 -120
  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 -41
  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 -11
  18. package/dist/internal/getSeamlessUser.d.ts.map +0 -1
  19. package/dist/internal/getSeamlessUser.js +0 -32
  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 -84
  32. package/dist/middleware/requireAuth.d.ts +0 -9
  33. package/dist/middleware/requireAuth.d.ts.map +0 -1
  34. package/dist/middleware/requireAuth.js +0 -74
  35. package/dist/middleware/requireRole.d.ts +0 -9
  36. package/dist/middleware/requireRole.d.ts.map +0 -1
  37. package/dist/middleware/requireRole.js +0 -37
  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/LICENSE ADDED
@@ -0,0 +1,79 @@
1
+ GNU AFFERO GENERAL PUBLIC LICENSE
2
+ Version 3, 19 November 2007
3
+
4
+ Copyright (C) 2007 Free Software Foundation, Inc.
5
+ <https://fsf.org/>
6
+ Everyone is permitted to copy and distribute verbatim copies
7
+ of this license document, but changing it is not allowed.
8
+
9
+ This license is identical to the GNU General Public License, except that it also
10
+ ensures that software running as a network service makes its source code
11
+ available to users.
12
+
13
+ ---
14
+
15
+ TERMS AND CONDITIONS
16
+
17
+ 0. Definitions.
18
+
19
+ “This License” refers to version 3 of the GNU Affero General Public License.
20
+
21
+ “Copyright” also means copyright-like laws that apply to other kinds of works,
22
+ such as semiconductor masks.
23
+
24
+ The “Program” refers to any copyrightable work licensed under this License.
25
+ Each licensee is addressed as “you”.
26
+
27
+ To “modify” a work means to copy from or adapt all or part of the work in a
28
+ fashion requiring copyright permission, other than the making of an exact copy.
29
+
30
+ To “propagate” a work means to do anything with it that, without permission,
31
+ would make you directly or secondarily liable for infringement under applicable
32
+ copyright law, except executing it on a computer or modifying a private copy.
33
+
34
+ To “convey” a work means any kind of propagation that enables other parties to
35
+ make or receive copies.
36
+
37
+ An interactive user interface displays “Appropriate Legal Notices” to the extent
38
+ that it includes a convenient and prominently visible feature that displays an
39
+ appropriate copyright notice, and tells the user that there is no warranty for
40
+ the work (except to the extent that warranties are provided), that licensees may
41
+ convey the work under this License, and how to view a copy of this License.
42
+
43
+ ---
44
+
45
+ 13. Remote Network Interaction; Use with the GNU General Public License.
46
+
47
+ Notwithstanding any other provision of this License, if you modify the Program,
48
+ your modified version must prominently offer all users interacting with it
49
+ remotely through a computer network an opportunity to receive the Corresponding
50
+ Source of your version by providing access to the Corresponding Source from a
51
+ network server at no charge, through some standard or customary means of
52
+ facilitating copying of software.
53
+
54
+ ---
55
+
56
+ 15. Disclaimer of Warranty.
57
+
58
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
59
+ EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER
60
+ PARTIES PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER
61
+ EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
62
+ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
63
+
64
+ ---
65
+
66
+ 16. Limitation of Liability.
67
+
68
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY
69
+ COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS
70
+ PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL,
71
+ INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE
72
+ THE PROGRAM.
73
+
74
+ ---
75
+
76
+ END OF TERMS AND CONDITIONS
77
+
78
+ You should have received a copy of the GNU Affero General Public License along
79
+ with this program. If not, see <https://www.gnu.org/licenses/>.
package/LICENSE.md ADDED
@@ -0,0 +1,26 @@
1
+ # License
2
+
3
+ Seamless Auth Server - Express ("@seamlessauth/express") is licensed under the **GNU Affero General Public License v3.0 (AGPL-3.0-only)**.
4
+
5
+ - SPDX: `AGPL-3.0-only`
6
+
7
+ ## What this means (high level)
8
+
9
+ - You are free to **use**, **modify**, and **self-host** this software.
10
+ - If you **modify** this software and **run it as a network service** (for example, hosting it for others to use), you must **make the complete corresponding source code of your modified version available** to users of that service, under the AGPL.
11
+
12
+ This summary is not legal advice and does not replace the license text.
13
+
14
+ ## Full license text
15
+
16
+ The full license text is available here:
17
+
18
+ - https://www.gnu.org/licenses/agpl-3.0.html
19
+
20
+ You should include a copy of the AGPLv3 license in your distribution. If this repository does not contain the full license text yet, add it as `LICENSE` or `LICENSE.txt` (recommended), and keep this `LICENSE.md` as the human-friendly summary.
21
+
22
+ ## Commercial licensing
23
+
24
+ If you would like to embed Seamless Auth API into a proprietary product, redistribute it under different terms, or offer it as a managed service without AGPL obligations, commercial licensing may be available.
25
+
26
+ Contact: support@seamlessauth.com
package/README.md CHANGED
@@ -1,78 +1,92 @@
1
- # @seamless-auth/server-express
1
+ # @seamless-auth/express
2
2
 
3
- ### Seamless Auth Express Adapter
3
+ [![npm version](https://img.shields.io/npm/v/@seamless-auth/express.svg)](https://www.npmjs.com/package/@seamless-auth/express)
4
+ [![test coverage](https://img.shields.io/badge/coverage-coming%20soon-lightgrey)](#testing)
5
+ [![license](https://img.shields.io/badge/license-AGPL--3.0-blue)](#license)
4
6
 
5
- A secure, passwordless **server-side adapter** that connects your Express API to a private Seamless Auth Server.
7
+ ### Seamless Auth Express Adapter
6
8
 
7
- It proxies all authentication flows, manages signed cookies, and gives you out-of-the-box middleware for verifying users and enforcing roles.
9
+ A secure, passwordless **server-side adapter** for Express that connects your API to a private **Seamless Auth Server**.
10
+
11
+ This package:
12
+
13
+ - Proxies authentication flows
14
+ - Manages signed, HttpOnly session cookies
15
+ - Enforces authentication and authorization in your API
16
+ - Handles all API ↔ Auth Server communication via short-lived service tokens
8
17
 
9
18
  > **npm:** https://www.npmjs.com/package/@seamless-auth/express
10
19
  > **Docs:** https://docs.seamlessauth.com
11
20
  > **Repo:** https://github.com/fells-code/seamless-auth-server
12
21
 
13
- > Couple with https://github.com/fells-code/seamless-auth/react for an end to end seamless experience
14
-
15
- > Or get a full starter application with https://github.com/fells-code/create-seamless
22
+ Pair this with:
16
23
 
17
- ---
24
+ - **React SDK:** https://github.com/fells-code/seamless-auth-react
25
+ - **Starter app:** https://github.com/fells-code/create-seamless
18
26
 
19
27
  ---
20
28
 
21
29
  ## Installation
22
30
 
23
31
  ```bash
24
- npm install @seamless-auth/server-express
32
+ npm install @seamless-auth/express
25
33
  # or
26
- yarn add @seamless-auth/server-express
34
+ yarn add @seamless-auth/express
27
35
  ```
28
36
 
29
- ## Quick Example
37
+ ---
38
+
39
+ ## Quick Start
30
40
 
31
41
  ```ts
32
42
  import express from "express";
33
43
  import cookieParser from "cookie-parser";
34
- import createSeamlessAuthServer, {
44
+ import {
45
+ createSeamlessAuthServer,
35
46
  requireAuth,
36
47
  requireRole,
37
- } from "@seamless-auth/server-express";
48
+ } from "@seamless-auth/express";
38
49
 
39
50
  const app = express();
51
+ app.use(express.json());
40
52
  app.use(cookieParser());
41
53
 
42
- // Public Seamless Auth endpoints
54
+ // Mount Seamless Auth routes
43
55
  app.use(
44
56
  "/auth",
45
- createSeamlessAuthServer({ authServerUrl: process.env.AUTH_SERVER_URL! })
57
+ createSeamlessAuthServer({
58
+ authServerUrl: process.env.AUTH_SERVER_URL!,
59
+ }),
46
60
  );
47
61
 
48
- // Everything after this line requires authentication
62
+ // Everything below requires authentication
49
63
  app.use(requireAuth());
50
64
 
51
- app.get("/api/me", (req, res) => res.json({ user: (req as any).user }));
52
- app.get("/admin", requireRole("admin"), (req, res) =>
53
- res.json({ message: "Welcome admin!" })
54
- );
65
+ app.get("/api/me", (req, res) => {
66
+ res.json({ user: req.user });
67
+ });
68
+
69
+ app.get("/admin", requireRole("admin"), (req, res) => {
70
+ res.json({ message: "Welcome admin!" });
71
+ });
55
72
 
56
- app.listen(5000, () => console.log("Portal API running on :5000"));
73
+ app.listen(5000, () => console.log("API running on http://localhost:3000"));
57
74
  ```
58
75
 
59
76
  ---
60
77
 
61
- # Full Documentation
62
-
63
78
  ## Overview
64
79
 
65
- `@seamless-auth/express` lets your backend API act as an authentication and authorization server using Seamless Auth.
80
+ `@seamless-auth/express` lets your backend API act as the **security boundary** for authentication and authorization.
66
81
 
67
- It transparently proxies and validates authentication flows so your frontend can use a single API endpoint for:
82
+ Your API:
68
83
 
69
- - Login / Registration / Logout
70
- - User introspection (`/auth/me`)
71
- - Session cookies (signed JWTs)
72
- - Role & permission guards
73
- - Internal Auth Server communication (JWKS + service tokens)
84
+ - owns user session cookies
85
+ - verifies identity locally
86
+ - asserts identity upstream using service tokens
87
+ - never forwards browser cookies to the Auth Server
74
88
 
75
- Everything happens securely between your API and a private Seamless Auth Server.
89
+ This keeps trust boundaries clean and auditable.
76
90
 
77
91
  ---
78
92
 
@@ -84,9 +98,9 @@ Everything happens securely between your API and a private Seamless Auth Server.
84
98
 
85
99
  [Your Express API]
86
100
  ├─ createSeamlessAuthServer() ← mounts /auth routes
87
- ├─ requireAuth() ← verifies signed cookie JWT
88
- ├─ requireRole('admin') ← role-based guard
89
- └─ getSeamlessUser() ← calls Auth Server
101
+ ├─ requireAuth() ← verifies access cookie
102
+ ├─ requireRole("admin") ← role-based guard
103
+ └─ getSeamlessUser() ← optional user hydration
90
104
 
91
105
 
92
106
  [Private Seamless Auth Server]
@@ -96,13 +110,14 @@ Everything happens securely between your API and a private Seamless Auth Server.
96
110
 
97
111
  ## Environment Variables
98
112
 
99
- | Variable | Description | Example |
100
- | ----------------------------- | -------------------------------------- | ------------------------- |
101
- | `AUTH_SERVER_URL` | Base URL of your Seamless Auth Server | `https://auth.client.com` |
102
- | `SEAMLESS_COOKIE_SIGNING_KEY` | Secret key for signing JWT cookies | `base64:...` |
103
- | `SEAMLESS_SERVICE_TOKEN` | Private key for API → Auth Server JWTs | RSA PEM |
104
- | `SERVICE_JWT_KEYID` | Key ID for JWKS | `service-main` |
105
- | `COOKIE_DOMAIN` | Domain for cookies | `.client.com` |
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` |
106
121
 
107
122
  ---
108
123
 
@@ -110,35 +125,35 @@ Everything happens securely between your API and a private Seamless Auth Server.
110
125
 
111
126
  ### `createSeamlessAuthServer(options)`
112
127
 
113
- Mounts an Express router exposing the full Seamless Auth flow:
128
+ Mounts an Express router that exposes the full Seamless Auth flow under `/auth`.
129
+
130
+ Routes include:
114
131
 
115
132
  - `/auth/login/start`
116
133
  - `/auth/login/finish`
117
- - `/auth/webauthn/...`
118
- - `/auth/registration/...`
119
- - `/auth/me`
134
+ - `/auth/webauthn/*`
135
+ - `/auth/registration/*`
136
+ - `/auth/users/me`
120
137
  - `/auth/logout`
121
138
 
122
139
  **Options**
123
140
 
124
141
  ```ts
125
142
  {
126
- authServerUrl: string; // required
127
- cookieDomain?: string;
128
- cookieNameOverrides?: {
129
- preauth?: string;
130
- registration?: string;
131
- access?: string;
132
- };
143
+ authServerUrl: string; // required
144
+ cookieDomain?: string; // optional (defaults to host)
145
+ accessCookieName?: string;
146
+ registrationCookieName?: string;
147
+ refreshCookieName?: string;
148
+ preAuthCookieName?: string;
133
149
  }
134
150
  ```
135
151
 
136
152
  ---
137
153
 
138
- ### `requireAuth(cookieName?: string)`
154
+ ### `requireAuth(options?)`
139
155
 
140
- Middleware that validates the signed access cookie (`seamless_auth_access` by default)
141
- and attaches the decoded user payload to `req.user`.
156
+ Express middleware that verifies a signed access cookie and attaches the decoded user payload to `req.user`.
142
157
 
143
158
  ```ts
144
159
  app.get("/api/profile", requireAuth(), (req, res) => {
@@ -148,10 +163,11 @@ app.get("/api/profile", requireAuth(), (req, res) => {
148
163
 
149
164
  ---
150
165
 
151
- ### `requireRole(role: string, cookieName?: string)`
166
+ ### `requireRole(role: string)`
167
+
168
+ Role-based authorization middleware.
152
169
 
153
- Role-based authorization guard.
154
- Blocks non-matching roles with HTTP 403.
170
+ Blocks requests when the authenticated user does not have the required role.
155
171
 
156
172
  ```ts
157
173
  app.get("/admin", requireRole("admin"), (req, res) => {
@@ -163,106 +179,67 @@ app.get("/admin", requireRole("admin"), (req, res) => {
163
179
 
164
180
  ### `getSeamlessUser(req, authServerUrl, cookieName?)`
165
181
 
166
- Calls the Auth Server’s `/internal/session/introspect` endpoint using a signed service JWT
167
- and returns the Seamless user object.
182
+ Optional helper that calls the Auth Server to retrieve the **fully hydrated user object**.
183
+
184
+ This does **not** enforce authentication.
168
185
 
169
186
  ```ts
170
- const user = await getSeamlessUser(req, process.env.AUTH_SERVER_URL!);
187
+ const user = await getSeamlessUser(req, process.env.AUTH_SERVER_URL);
171
188
  ```
172
189
 
173
- User shape
190
+ Returned shape (example):
174
191
 
175
192
  ```ts
176
193
  {
177
194
  id: string;
178
195
  email: string;
179
196
  phone: string;
180
- roles: string[]
197
+ roles: string[];
181
198
  }
182
199
  ```
183
200
 
201
+ ---
202
+
184
203
  ## End-to-End Flow
185
204
 
186
205
  1. **Frontend** → `/auth/login/start`
187
- API proxies to Seamless Auth Server
188
- → sets short-lived pre-auth cookie.
206
+ API proxies request and sets a short-lived _pre-auth_ cookie.
189
207
 
190
208
  2. **Frontend** → `/auth/webauthn/finish`
191
- API proxies, validates, sets access cookie (`seamless_auth_access`).
209
+ API verifies response and sets a signed access cookie.
192
210
 
193
- 3. **Subsequent API calls** → `/api/...`
194
- `requireAuth()` verifies cookie and attaches user.
195
- → Role routes use `requireRole()`.
211
+ 3. **API routes** → `/api/*`
212
+ `requireAuth()` verifies the cookie and attaches `req.user`.
196
213
 
197
214
  ---
198
215
 
199
216
  ## Local Development
200
217
 
201
- In order to develop with your Seamless Auth server instance, you will need to have:
202
-
203
- - Created an account @ https://dashboard.seamlessauth.com
204
- - Created a new Seamless Auth application
205
-
206
- Example env:
207
-
208
218
  ```bash
209
- AUTH_SERVER_URL=http://https://<identifier>.seamlessauth.com # Found in the portal
210
- COOKIE_DOMAIN=localhost # Or frontend domain in prod
211
- SEAMLESS_COOKIE_SIGNING_KEY=local-secret-key # Found in the portal
219
+ AUTH_SERVER_URL=http://localhost:5312
220
+ SEAMLESS_SERVICE_TOKEN=generated-secret
221
+ COOKIE_SIGNING_KEY=local-dev-key
222
+ FRONTEND_URL=https://localhost:5001
212
223
  ```
213
224
 
214
225
  ---
215
226
 
216
- ## Example Middleware Stack
217
-
218
- ```ts
219
- const AUTH_SERVER_URL = process.env.AUTH_SERVER_URL!;
220
- app.use(cors({ origin: "http://localhost:5001", credentials: true }));
221
- app.use(express.json());
222
- app.use(cookieParser());
223
- app.use("/auth", createSeamlessAuthServer({ authServerUrl: AUTH_SERVER_URL }));
224
- app.use(requireAuth());
225
- ```
226
-
227
- ---
228
-
229
- ## Security Model
230
-
231
- | Layer | Auth Mechanism | Signed By |
232
- | --------------------- | ------------------------------------- | ------------------ |
233
- | **Frontend ↔ API** | Signed JWT in HttpOnly cookie (HS256) | Client API |
234
- | **API ↔ Auth Server** | Bearer Service JWT (RS256) | API’s private key |
235
- | **Auth Server** | Validates service tokens via JWKS | Seamless Auth JWKS |
236
-
237
- All tokens and cookies are stateless and cryptographically verifiable.
238
-
239
- ---
240
-
241
227
  ## Testing
242
228
 
243
- You can mock `requireAuth` and test Express routes via `supertest`.
244
-
245
- Example:
229
+ This package includes **Express smoke tests** using `supertest`.
246
230
 
247
- ```ts
248
- import { requireAuth } from "@seamless-auth/server-express";
249
- app.get("/api/test", requireAuth(), (req, res) => res.json({ ok: true }));
250
- ```
231
+ Core authentication logic is tested separately in `@seamless-auth/core`.
251
232
 
252
233
  ---
253
234
 
254
- ## Roadmap
235
+ ## License
255
236
 
256
- | Feature | Status |
257
- | -------------------------------------------- | ----------- |
258
- | JWKS-verified response signing | ✅ |
259
- | OIDC discovery & SSO readiness | planned |
260
- | Federation (Google / Okta) | future |
261
- | Multi-framework adapters (Next.js / Fastify) | coming soon |
237
+ **AGPL-3.0-only** © 2026 Fells Code LLC
262
238
 
263
- ---
239
+ This license ensures:
264
240
 
265
- ## License
241
+ - transparency of security-critical code
242
+ - freedom to self-host and modify
243
+ - sustainability of the managed service offering
266
244
 
267
- MIT © 2025 Fells Code LLC
268
- Part of the **Seamless Auth** ecosystem.
245
+ See [`LICENSE`](./LICENSE) for details.
package/dist/index.d.ts CHANGED
@@ -1,7 +1,190 @@
1
- import { createSeamlessAuthServer } from "./createServer";
2
- export { requireAuth } from "./middleware/requireAuth";
3
- export { requireRole } from "./middleware/requireRole";
4
- export { getSeamlessUser } from "./internal/getSeamlessUser";
5
- export type { SeamlessAuthServerOptions } from "./types";
6
- export default createSeamlessAuthServer;
7
- //# sourceMappingURL=index.d.ts.map
1
+ import { Router, Request, Response, NextFunction, RequestHandler } from 'express';
2
+
3
+ type SeamlessAuthServerOptions = {
4
+ authServerUrl: string;
5
+ cookieSecret: string;
6
+ serviceSecret: string;
7
+ jwksKid?: string;
8
+ cookieDomain?: string;
9
+ accessCookieName?: string;
10
+ registrationCookieName?: string;
11
+ refreshCookieName?: string;
12
+ preAuthCookieName?: string;
13
+ };
14
+ /**
15
+ * Creates an Express Router that proxies all authentication traffic to a Seamless Auth server.
16
+ *
17
+ * This helper wires your API backend to a Seamless Auth instance running in
18
+ * "server mode." It automatically forwards login, registration, WebAuthn,
19
+ * logout, token refresh, and session validation routes to the auth server
20
+ * and handles all cookie management required for a seamless login flow.
21
+ *
22
+ * ### Responsibilities
23
+ * - Proxies all `/auth/*` routes to the upstream Seamless Auth server
24
+ * - Manages `access`, `registration`, `pre-auth`, and `refresh` cookies
25
+ * - Normalizes cookie settings for cross-domain or same-domain deployments
26
+ * - Ensures authentication routes behave consistently across environments
27
+ * - Provides shared middleware for auth flows
28
+ *
29
+ * ### Cookie Types
30
+ * - **accessCookie** – long-lived session cookie for authenticated API requests
31
+ * - **registrationCookie** – ephemeral cookie used during registration and OTP/WebAuthn flows
32
+ * - **preAuthCookie** – short-lived cookie used during login initiation
33
+ * - **refreshCookie** – opaque refresh token cookie used to rotate session tokens
34
+ *
35
+ * All cookie names and their domains may be customized via the `opts` parameter.
36
+ *
37
+ * ### Example
38
+ * ```ts
39
+ * app.use("/auth", createSeamlessAuthServer({
40
+ * authServerUrl: "https://identifier.seamlessauth.com",
41
+ * cookieDomain: "mycompany.com",
42
+ * cookieSecret: "someLongRandomValue"
43
+ * serviceSecret: "someLongRandomValueToo"
44
+ * jwksKid: "dev-main"
45
+ * accessCookieName: "sa_access",
46
+ * registrationCookieName: "sa_registration",
47
+ * refreshCookieName: "sa_refresh",
48
+ * }));
49
+ * ```
50
+ *
51
+ * @param opts - Configuration options for the Seamless Auth proxy:
52
+ * - `authServerUrl` — Base URL of your Seamless Auth instance (required)
53
+ * - `cookieSecret` — The value to encode your cookies secrets with (required)
54
+ * - `serviceSecret` - An machine to machine shared secret that matches your auth servers (required)
55
+ * - `jwksKid` - The active jwks KID
56
+ * - `cookieDomain` — Domain attribute applied to all auth cookies
57
+ * - `accessCookieName` — Name of the session access cookie
58
+ * - `registrationCookieName` — Name of the ephemeral registration cookie
59
+ * - `refreshCookieName` — Name of the refresh token cookie
60
+ * - `preAuthCookieName` — Name of the cookie used during login initiation
61
+ *
62
+ * @returns An Express `Router` preconfigured with all Seamless Auth routes.
63
+ */
64
+ declare function createSeamlessAuthServer(opts: SeamlessAuthServerOptions): Router;
65
+
66
+ interface RequireAuthOptions {
67
+ cookieName?: string;
68
+ cookieSecret: string;
69
+ }
70
+ /**
71
+ * Express middleware that enforces authentication using Seamless Auth cookies.
72
+ *
73
+ * This guard verifies the signed access cookie generated by the Seamless Auth
74
+ * server. If the access cookie is valid and unexpired, the decoded session
75
+ * payload is attached to `req.user` and the request proceeds.
76
+ *
77
+ * If the access cookie is expired or missing *but* a valid refresh cookie is
78
+ * present, the middleware automatically attempts a silent token refresh using
79
+ * the Seamless Auth server. When successful, new session cookies are issued and
80
+ * the request continues with an updated `req.user`.
81
+ *
82
+ * If neither the access token nor refresh token can validate the session,
83
+ * the middleware returns a 401 Unauthorized error and prevents further
84
+ * route execution.
85
+ *
86
+ * ### Responsibilities
87
+ * - Validates the Seamless Auth session access cookie
88
+ * - Attempts refresh-token–based session renewal when necessary
89
+ * - Populates `req.user` with the verified session payload
90
+ * - Handles all cookie rewriting during refresh flows
91
+ * - Acts as a request-level authentication guard for API routes
92
+ *
93
+ * ### Cookie Parameters
94
+ * - **cookieName** — Name of the access cookie that holds the signed session JWT
95
+ * - **refreshCookieName** — Name of the refresh cookie used for silent token refresh
96
+ * - **cookieDomain** — Domain or path value applied to issued cookies
97
+ *
98
+ * ### Example
99
+ * ```ts
100
+ * // Protect a route
101
+ * app.get("/api/me", requireAuth(), (req, res) => {
102
+ * res.json({ user: req.user });
103
+ * });
104
+ *
105
+ * // Custom cookie names (if your Seamless Auth server uses overrides)
106
+ * app.use(
107
+ * "/internal",
108
+ * requireAuth("sa_access", "sa_refresh", "mycompany.com"),
109
+ * internalRouter
110
+ * );
111
+ * ```
112
+ *
113
+ * @param cookieName - The access cookie name. Defaults to `"seamless-access"`.
114
+ * @param refreshCookieName - The refresh cookie name used for session rotation. Defaults to `"seamless-refresh"`.
115
+ * @param cookieDomain - Domain or path used when rewriting cookies. Defaults to `"/"`.
116
+ *
117
+ * @returns An Express middleware function that enforces Seamless Auth
118
+ * authentication on incoming requests.
119
+ */
120
+ interface RequireAuthOptions {
121
+ cookieName?: string;
122
+ cookieSecret: string;
123
+ }
124
+ /**
125
+ * Express middleware that enforces authentication
126
+ * using an already-issued Seamless Auth access cookie.
127
+ *
128
+ * NOTE:
129
+ * - This middleware does NOT attempt token refresh.
130
+ * - Refresh is handled upstream by ensureCookies().
131
+ */
132
+ declare function requireAuth(opts: RequireAuthOptions): (req: Request, res: Response, next: NextFunction) => void;
133
+
134
+ /**
135
+ * Express middleware that enforces role-based authorization for Seamless Auth.
136
+ *
137
+ * This middleware assumes `requireAuth()` has already:
138
+ * - authenticated the request
139
+ * - populated `req.user` with the authenticated session payload
140
+ *
141
+ * `requireRole` performs **authorization only**. It does not inspect cookies,
142
+ * verify tokens, or read environment variables.
143
+ *
144
+ * If any of the required roles are present on the user, access is granted.
145
+ * Otherwise, a 403 Forbidden response is returned.
146
+ *
147
+ * * ### Example
148
+ * ```ts
149
+ * // Require a single role
150
+ * app.get("/admin/users",
151
+ * requireAuth(),
152
+ * requireRole("admin"),
153
+ * (req, res) => {
154
+ * res.send("Welcome admin!");
155
+ * }
156
+ * );
157
+ *
158
+ * // Allow any of multiple roles
159
+ * app.post("/settings",
160
+ * requireAuth(),
161
+ * requireRole(["admin", "supervisor"]),
162
+ * updateSettingsHandler
163
+ * );
164
+ *
165
+ * @param requiredRoles - A role or list of roles required to access the route
166
+ */
167
+ declare function requireRole(requiredRoles: string | string[]): RequestHandler;
168
+
169
+ interface EnsureCookiesMiddlewareOptions {
170
+ authServerUrl: string;
171
+ cookieDomain?: string;
172
+ accessCookieName: string;
173
+ registrationCookieName: string;
174
+ refreshCookieName: string;
175
+ preAuthCookieName: string;
176
+ cookieSecret: string;
177
+ serviceSecret: string;
178
+ issuer: string;
179
+ audience: string;
180
+ keyId: string;
181
+ }
182
+ declare function createEnsureCookiesMiddleware(opts: EnsureCookiesMiddlewareOptions): (req: Request, res: Response, next: NextFunction) => Promise<void>;
183
+
184
+ declare function getSeamlessUser(req: Request, opts: {
185
+ authServerUrl: string;
186
+ cookieSecret: string;
187
+ cookieName?: string;
188
+ }): Promise<any>;
189
+
190
+ export { type SeamlessAuthServerOptions, createEnsureCookiesMiddleware, createSeamlessAuthServer as default, getSeamlessUser, requireAuth, requireRole };