@seamless-auth/express 0.0.0 → 0.0.1-beta.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.
Files changed (2) hide show
  1. package/README.md +258 -7
  2. package/package.json +2 -5
package/README.md CHANGED
@@ -1,13 +1,264 @@
1
1
  # @seamless-auth/server-express
2
2
 
3
- Drop-in Express adapter for Seamless Auth “server mode” authentication.
3
+ ### Seamless Auth Express Adapter
4
4
 
5
- ```js
5
+ A secure, passwordless **server-side adapter** that connects your Express API to a private Seamless Auth Server.
6
+
7
+ It proxies all authentication flows, manages signed cookies, and gives you out-of-the-box middleware for verifying users and enforcing roles.
8
+
9
+ > **npm:** https://www.npmjs.com/package/@seamless-auth/express
10
+ > **Docs:** https://docs.seamlessauth.com
11
+ > **Repo:** https://github.com/fells-code/seamless-auth-server
12
+
13
+
14
+ > Couple with https://github.com/fells-code/seamless-auth/react for an end to end seamless experience
15
+
16
+ > Or get a full starter application with https://github.com/fells-code/create-seamless
17
+
18
+ ---
19
+
20
+ ---
21
+
22
+ ## Installation
23
+
24
+ ```bash
25
+ npm install @seamless-auth/server-express
26
+ # or
27
+ yarn add @seamless-auth/server-express
28
+ ```
29
+
30
+
31
+ ## Quick Example
32
+
33
+ ```ts
6
34
  import express from "express";
7
- import createSeamlessAuthServer from "@seamless-auth/server-express";
35
+ import cookieParser from "cookie-parser";
36
+ import createSeamlessAuthServer, { requireAuth, requireRole } from "@seamless-auth/server-express";
8
37
 
9
38
  const app = express();
10
- app.use("/auth", createSeamlessAuthServer({
11
- authServerUrl: process.env.AUTH_SERVER_URL,
12
- cookieDomain: ".myapp.com"
13
- }));
39
+ app.use(cookieParser());
40
+
41
+ // Public Seamless Auth endpoints
42
+ app.use("/auth", createSeamlessAuthServer({ authServerUrl: process.env.AUTH_SERVER_URL! }));
43
+
44
+ // Everything after this line requires authentication
45
+ app.use(requireAuth());
46
+
47
+ app.get("/api/me", (req, res) => res.json({ user: (req as any).user }));
48
+ app.get("/admin", requireRole("admin"), (req, res) => res.json({ message: "Welcome admin!" }));
49
+
50
+ app.listen(5000, () => console.log("Portal API running on :5000"));
51
+ ```
52
+
53
+ ---
54
+
55
+ # Full Documentation
56
+
57
+ ## Overview
58
+
59
+ `@seamless-auth/express` lets your backend API act as an authentication and authorization server using Seamless Auth.
60
+
61
+ It transparently proxies and validates authentication flows so your frontend can use a single API endpoint for:
62
+
63
+ - Login / Registration / Logout
64
+ - User introspection (`/auth/me`)
65
+ - Session cookies (signed JWTs)
66
+ - Role & permission guards
67
+ - Internal Auth Server communication (JWKS + service tokens)
68
+
69
+ Everything happens securely between your API and a private Seamless Auth Server.
70
+
71
+
72
+
73
+ ---
74
+
75
+ ## Architecture
76
+
77
+ ```
78
+ [Frontend App]
79
+
80
+
81
+ [Your Express API]
82
+ ├─ createSeamlessAuthServer() ← mounts /auth routes
83
+ ├─ requireAuth() ← verifies signed cookie JWT
84
+ ├─ requireRole('admin') ← role-based guard
85
+ └─ getSeamlessUser() ← calls Auth Server
86
+
87
+
88
+ [Private Seamless Auth Server]
89
+ ```
90
+
91
+ ---
92
+
93
+ ## Environment Variables
94
+
95
+ | Variable | Description | Example |
96
+ |-----------|--------------|----------|
97
+ | `AUTH_SERVER_URL` | Base URL of your Seamless Auth Server | `https://auth.client.com` |
98
+ | `SEAMLESS_COOKIE_SIGNING_KEY` | Secret key for signing JWT cookies | `base64:...` |
99
+ | `SERVICE_JWT_PRIVATE_KEY` | Private key for API → Auth Server JWTs | RSA PEM |
100
+ | `SERVICE_JWT_KEYID` | Key ID for JWKS | `service-main` |
101
+ | `COOKIE_DOMAIN` | Domain for cookies | `.client.com` |
102
+
103
+ ---
104
+
105
+ ## API Reference
106
+
107
+ ### `createSeamlessAuthServer(options)`
108
+
109
+ Mounts an Express router exposing the full Seamless Auth flow:
110
+
111
+ - `/auth/login/start`
112
+ - `/auth/login/finish`
113
+ - `/auth/webauthn/...`
114
+ - `/auth/registration/...`
115
+ - `/auth/me`
116
+ - `/auth/logout`
117
+
118
+ **Options**
119
+
120
+ ```ts
121
+ {
122
+ authServerUrl: string; // required
123
+ cookieDomain?: string;
124
+ cookieNameOverrides?: {
125
+ preauth?: string;
126
+ registration?: string;
127
+ access?: string;
128
+ };
129
+ }
130
+ ```
131
+
132
+ ---
133
+
134
+ ### `requireAuth(cookieName?: string)`
135
+
136
+ Middleware that validates the signed access cookie (`seamless_auth_access` by default)
137
+ and attaches the decoded user payload to `req.user`.
138
+
139
+ ```ts
140
+ app.get("/api/profile", requireAuth(), (req, res) => {
141
+ res.json({ user: req.user });
142
+ });
143
+ ```
144
+
145
+ ---
146
+
147
+ ### `requireRole(role: string, cookieName?: string)`
148
+
149
+ Role-based authorization guard.
150
+ Blocks non-matching roles with HTTP 403.
151
+
152
+ ```ts
153
+ app.get("/admin", requireRole("admin"), (req, res) => {
154
+ res.json({ message: "Welcome admin!" });
155
+ });
156
+ ```
157
+
158
+ ---
159
+
160
+ ### `getSeamlessUser(req, authServerUrl, cookieName?)`
161
+
162
+ Calls the Auth Server’s `/internal/session/introspect` endpoint using a signed service JWT
163
+ and returns the Seamless user object.
164
+
165
+ ```ts
166
+ const user = await getSeamlessUser(req, process.env.AUTH_SERVER_URL!);
167
+ ```
168
+
169
+ User shape
170
+ ```ts
171
+ {
172
+ id: string;
173
+ email: string;
174
+ phone: string;
175
+ roles: string[]
176
+ }
177
+ ```
178
+
179
+ ## End-to-End Flow
180
+
181
+ 1. **Frontend** → `/auth/login/start`
182
+ → API proxies to Seamless Auth Server
183
+ → sets short-lived pre-auth cookie.
184
+
185
+ 2. **Frontend** → `/auth/webauthn/finish`
186
+ → API proxies, validates, sets access cookie (`seamless_auth_access`).
187
+
188
+ 3. **Subsequent API calls** → `/api/...`
189
+ → `requireAuth()` verifies cookie and attaches user.
190
+ → Role routes use `requireRole()`.
191
+
192
+ ---
193
+
194
+ ## Local Development
195
+
196
+ In order to develop with your Seamless Auth server instance, you will need to have:
197
+
198
+ - Created an account @ https://dashboard.seamlessauth.com
199
+ - Created a new Seamless Auth application
200
+
201
+ Example env:
202
+
203
+ ```bash
204
+ AUTH_SERVER_URL=http://https://<identifier>.seamlessauth.com # Found in the portal
205
+ COOKIE_DOMAIN=localhost # Or frontend domain in prod
206
+ SEAMLESS_COOKIE_SIGNING_KEY=local-secret-key # Found in the portal
207
+ ```
208
+
209
+ ---
210
+
211
+ ## Example Middleware Stack
212
+
213
+ ```ts
214
+ const AUTH_SERVER_URL = process.env.AUTH_SERVER_URL!;
215
+ app.use(cors({ origin: "https://localhost:5001", credentials: true }));
216
+ app.use(express.json());
217
+ app.use(cookieParser());
218
+ app.use("/auth", createSeamlessAuthServer({ authServerUrl: AUTH_SERVER_URL }));
219
+ app.use(requireAuth());
220
+ ```
221
+
222
+ ---
223
+
224
+ ## Security Model
225
+
226
+ | Layer | Auth Mechanism | Signed By |
227
+ |--------|----------------|------------|
228
+ | **Frontend ↔ API** | Signed JWT in HttpOnly cookie (HS256) | Client API |
229
+ | **API ↔ Auth Server** | Bearer Service JWT (RS256) | API’s private key |
230
+ | **Auth Server** | Validates service tokens via JWKS | Seamless Auth JWKS |
231
+
232
+ All tokens and cookies are stateless and cryptographically verifiable.
233
+
234
+ ---
235
+
236
+ ## Testing
237
+
238
+ You can mock `requireAuth` and test Express routes via `supertest`.
239
+
240
+ Example:
241
+
242
+ ```ts
243
+ import { requireAuth } from "@seamless-auth/server-express";
244
+ app.get("/api/test", requireAuth(), (req, res) => res.json({ ok: true }));
245
+ ```
246
+
247
+ ---
248
+
249
+ ## Roadmap
250
+
251
+ | Feature | Status |
252
+ |----------|---------|
253
+ | JWKS-verified response signing | ✅ |
254
+ | OIDC discovery & SSO readiness | planned |
255
+ | Federation (Google / Okta) | future |
256
+ | Multi-framework adapters (Next.js / Fastify) | coming soon |
257
+
258
+ ---
259
+
260
+ ## License
261
+
262
+ MIT © 2025 Fells Code LLC
263
+ Part of the **Seamless Auth** ecosystem.
264
+
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seamless-auth/express",
3
- "version": "0.0.0",
3
+ "version": "0.0.1-beta.1",
4
4
  "description": "Express adapter for Seamless Auth passwordless authentication",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -26,12 +26,9 @@
26
26
  "cookie-parser": "^1.4.6",
27
27
  "jose": "^6.1.1",
28
28
  "jsonwebtoken": "^9.0.2",
29
- "node-fetch": "^3.3.2",
30
- "version-packages": "changeset version",
31
- "release": "changeset publish"
29
+ "node-fetch": "^3.3.2"
32
30
  },
33
31
  "devDependencies": {
34
- "@changesets/cli": "^2.29.7",
35
32
  "@types/cookie-parser": "^1.4.10",
36
33
  "@types/jsonwebtoken": "^9.0.10",
37
34
  "typescript": "^5.5.0"