@sigma-auth/better-auth-plugin 0.0.5 → 0.0.7
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 +223 -23
- package/dist/next/index.d.ts.map +1 -1
- package/dist/next/index.js +2 -1
- package/dist/next/index.js.map +1 -1
- package/dist/server/index.d.ts +13 -0
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +10 -1
- package/dist/server/index.js.map +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -19,9 +19,23 @@ This package provides multiple entry points for different use cases:
|
|
|
19
19
|
- **`/next`** - Next.js API route handlers
|
|
20
20
|
- **`/provider`** - Better Auth server plugin for OIDC provider
|
|
21
21
|
|
|
22
|
-
## Architecture
|
|
22
|
+
## Architecture
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
### OAuth Flow (Cross-Domain)
|
|
25
|
+
|
|
26
|
+
When your app authenticates with Sigma Identity (or another Better Auth server on a different domain), you use OAuth/OIDC flow with tokens:
|
|
27
|
+
|
|
28
|
+
1. User clicks sign in → redirects to `auth.sigmaidentity.com`
|
|
29
|
+
2. User authenticates with Bitcoin wallet
|
|
30
|
+
3. Redirects back to your app with authorization code
|
|
31
|
+
4. Your backend exchanges code for access tokens
|
|
32
|
+
5. **Store user data and tokens locally** (Context, Zustand, localStorage, etc.)
|
|
33
|
+
|
|
34
|
+
**Important:** Cross-domain cookies don't work due to browser security. Better Auth's `useSession` hook only works when the auth server is on the **same domain** as your app. For OAuth clients, you manage authentication state locally with tokens.
|
|
35
|
+
|
|
36
|
+
### Wallet Unlock Gate
|
|
37
|
+
|
|
38
|
+
This plugin fronts Better Auth's OIDC authorize endpoint to ensure wallet access is a prerequisite to authentication.
|
|
25
39
|
|
|
26
40
|
The client redirects to `/oauth2/authorize` (custom gate) instead of `/api/auth/oauth2/authorize` (Better Auth directly). The gate checks:
|
|
27
41
|
|
|
@@ -32,38 +46,193 @@ The client redirects to `/oauth2/authorize` (custom gate) instead of `/api/auth/
|
|
|
32
46
|
|
|
33
47
|
This makes Bitcoin identity the foundation of authentication.
|
|
34
48
|
|
|
35
|
-
## Quick Start (
|
|
49
|
+
## Quick Start (OAuth Client)
|
|
36
50
|
|
|
37
|
-
|
|
51
|
+
This is the standard setup for apps authenticating with Sigma Identity.
|
|
52
|
+
|
|
53
|
+
### 1. Environment Variables
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
# Your registered OAuth client ID
|
|
57
|
+
NEXT_PUBLIC_SIGMA_CLIENT_ID=your-app
|
|
58
|
+
|
|
59
|
+
# Member private key for signing token exchange requests (server-side only)
|
|
60
|
+
SIGMA_MEMBER_PRIVATE_KEY=your-member-wif
|
|
61
|
+
|
|
62
|
+
# Sigma Auth server URL
|
|
63
|
+
NEXT_PUBLIC_SIGMA_AUTH_URL=https://auth.sigmaidentity.com
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### 2. Create Auth Client
|
|
38
67
|
|
|
39
68
|
```typescript
|
|
69
|
+
// lib/auth.ts
|
|
40
70
|
import { createAuthClient } from "better-auth/client";
|
|
41
71
|
import { sigmaClient } from "@sigma-auth/better-auth-plugin/client";
|
|
42
72
|
|
|
43
73
|
export const authClient = createAuthClient({
|
|
44
|
-
baseURL: "https://auth.sigmaidentity.com",
|
|
74
|
+
baseURL: process.env.NEXT_PUBLIC_SIGMA_AUTH_URL || "https://auth.sigmaidentity.com",
|
|
45
75
|
plugins: [sigmaClient()],
|
|
46
76
|
});
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
### 2. Sign In
|
|
50
77
|
|
|
51
|
-
|
|
52
|
-
authClient.signIn
|
|
53
|
-
clientId: "your-app",
|
|
54
|
-
callbackURL: "/callback",
|
|
55
|
-
});
|
|
78
|
+
// Export sign in method for OAuth flow
|
|
79
|
+
export const signIn = authClient.signIn;
|
|
56
80
|
```
|
|
57
81
|
|
|
58
|
-
### 3.
|
|
82
|
+
### 3. Token Exchange API Route
|
|
83
|
+
|
|
84
|
+
This server-side endpoint exchanges the OAuth code for tokens.
|
|
59
85
|
|
|
60
86
|
```typescript
|
|
87
|
+
// app/api/auth/callback/route.ts
|
|
61
88
|
import { createCallbackHandler } from "@sigma-auth/better-auth-plugin/next";
|
|
62
89
|
|
|
63
90
|
export const runtime = "nodejs";
|
|
64
91
|
export const POST = createCallbackHandler();
|
|
65
92
|
```
|
|
66
93
|
|
|
94
|
+
### 4. OAuth Callback Page
|
|
95
|
+
|
|
96
|
+
This page handles the OAuth redirect and stores the authenticated user.
|
|
97
|
+
|
|
98
|
+
```typescript
|
|
99
|
+
// app/callback/page.tsx
|
|
100
|
+
"use client";
|
|
101
|
+
|
|
102
|
+
import { Suspense, useEffect, useState } from "react";
|
|
103
|
+
import { useRouter, useSearchParams } from "next/navigation";
|
|
104
|
+
import { authClient } from "@/lib/auth";
|
|
105
|
+
|
|
106
|
+
function CallbackContent() {
|
|
107
|
+
const router = useRouter();
|
|
108
|
+
const searchParams = useSearchParams();
|
|
109
|
+
const [error, setError] = useState<string | null>(null);
|
|
110
|
+
|
|
111
|
+
useEffect(() => {
|
|
112
|
+
const handleCallback = async () => {
|
|
113
|
+
try {
|
|
114
|
+
// Exchange code for tokens and get user data
|
|
115
|
+
const result = await authClient.sigma.handleCallback(searchParams);
|
|
116
|
+
|
|
117
|
+
// Store user data in your app's state management
|
|
118
|
+
// Example: Context, Zustand, localStorage, etc.
|
|
119
|
+
localStorage.setItem("sigma_user", JSON.stringify(result.user));
|
|
120
|
+
localStorage.setItem("sigma_access_token", result.access_token);
|
|
121
|
+
localStorage.setItem("sigma_id_token", result.id_token);
|
|
122
|
+
if (result.refresh_token) {
|
|
123
|
+
localStorage.setItem("sigma_refresh_token", result.refresh_token);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// Redirect to your app
|
|
127
|
+
router.push("/");
|
|
128
|
+
} catch (err: any) {
|
|
129
|
+
console.error("OAuth callback error:", err);
|
|
130
|
+
setError(err.message || "Authentication failed");
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
handleCallback();
|
|
135
|
+
}, [searchParams, router]);
|
|
136
|
+
|
|
137
|
+
if (error) {
|
|
138
|
+
return (
|
|
139
|
+
<div className="flex min-h-screen items-center justify-center">
|
|
140
|
+
<div className="text-center">
|
|
141
|
+
<h2 className="text-xl font-semibold text-red-600">Authentication Failed</h2>
|
|
142
|
+
<p className="mt-2 text-sm text-gray-600">{error}</p>
|
|
143
|
+
<button
|
|
144
|
+
onClick={() => router.push("/")}
|
|
145
|
+
className="mt-4 px-4 py-2 bg-blue-600 text-white rounded"
|
|
146
|
+
>
|
|
147
|
+
Return Home
|
|
148
|
+
</button>
|
|
149
|
+
</div>
|
|
150
|
+
</div>
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
return (
|
|
155
|
+
<div className="flex min-h-screen items-center justify-center">
|
|
156
|
+
<div className="text-center">
|
|
157
|
+
<h2 className="text-xl font-semibold">Completing sign in...</h2>
|
|
158
|
+
<p className="mt-2 text-sm text-gray-600">Please wait</p>
|
|
159
|
+
</div>
|
|
160
|
+
</div>
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
export default function CallbackPage() {
|
|
165
|
+
return (
|
|
166
|
+
<Suspense fallback={<div>Loading...</div>}>
|
|
167
|
+
<CallbackContent />
|
|
168
|
+
</Suspense>
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### 5. Sign In
|
|
174
|
+
|
|
175
|
+
```typescript
|
|
176
|
+
// In your sign-in button component
|
|
177
|
+
import { signIn } from "@/lib/auth";
|
|
178
|
+
|
|
179
|
+
const handleSignIn = () => {
|
|
180
|
+
signIn.sigma({
|
|
181
|
+
clientId: process.env.NEXT_PUBLIC_SIGMA_CLIENT_ID || "your-app",
|
|
182
|
+
callbackURL: "/callback",
|
|
183
|
+
});
|
|
184
|
+
};
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### 6. Access User Data
|
|
188
|
+
|
|
189
|
+
Since you're managing state locally, access user data from your state management solution:
|
|
190
|
+
|
|
191
|
+
```typescript
|
|
192
|
+
// Example with Context
|
|
193
|
+
import { createContext, useContext, useEffect, useState } from "react";
|
|
194
|
+
|
|
195
|
+
const AuthContext = createContext<{ user: SigmaUserInfo | null }>({ user: null });
|
|
196
|
+
|
|
197
|
+
export function AuthProvider({ children }) {
|
|
198
|
+
const [user, setUser] = useState<SigmaUserInfo | null>(null);
|
|
199
|
+
|
|
200
|
+
useEffect(() => {
|
|
201
|
+
const storedUser = localStorage.getItem("sigma_user");
|
|
202
|
+
if (storedUser) {
|
|
203
|
+
setUser(JSON.parse(storedUser));
|
|
204
|
+
}
|
|
205
|
+
}, []);
|
|
206
|
+
|
|
207
|
+
return <AuthContext.Provider value={{ user }}>{children}</AuthContext.Provider>;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
export const useAuth = () => useContext(AuthContext);
|
|
211
|
+
|
|
212
|
+
// In components
|
|
213
|
+
const { user } = useAuth();
|
|
214
|
+
const isAdmin = user?.bap?.id === process.env.ADMIN_BAP_ID;
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
## Alternative: Same-Domain Setup
|
|
218
|
+
|
|
219
|
+
If you run your own Better Auth server on the **same domain** as your app, you can use session cookies and the `useSession` hook:
|
|
220
|
+
|
|
221
|
+
```typescript
|
|
222
|
+
// lib/auth.ts
|
|
223
|
+
export const authClient = createAuthClient({
|
|
224
|
+
baseURL: "/api/auth", // Same domain
|
|
225
|
+
plugins: [sigmaClient()],
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
export const { useSession } = authClient;
|
|
229
|
+
|
|
230
|
+
// In components
|
|
231
|
+
const { data: session } = useSession();
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
This requires setting up Better Auth server with the Sigma provider plugin on your domain.
|
|
235
|
+
|
|
67
236
|
## Server Plugin (Auth Provider)
|
|
68
237
|
|
|
69
238
|
For building your own Sigma Identity server:
|
|
@@ -86,6 +255,45 @@ export const auth = betterAuth({
|
|
|
86
255
|
});
|
|
87
256
|
```
|
|
88
257
|
|
|
258
|
+
## Key Concepts
|
|
259
|
+
|
|
260
|
+
### OAuth Endpoints
|
|
261
|
+
|
|
262
|
+
When using OAuth flow, there are **two different endpoints**:
|
|
263
|
+
|
|
264
|
+
1. **OAuth Redirect URI** (`/callback`) - Where the auth server redirects after authorization
|
|
265
|
+
2. **Token Exchange API** (`/api/auth/callback`) - Internal endpoint that exchanges code for tokens
|
|
266
|
+
|
|
267
|
+
The redirect URI is what you configure in your OAuth client settings. The token exchange API is called internally by your callback page.
|
|
268
|
+
|
|
269
|
+
### Authentication Result
|
|
270
|
+
|
|
271
|
+
After successful authentication via `handleCallback()`, you receive:
|
|
272
|
+
|
|
273
|
+
```typescript
|
|
274
|
+
{
|
|
275
|
+
user: {
|
|
276
|
+
sub: string; // User ID
|
|
277
|
+
name?: string; // Display name
|
|
278
|
+
email?: string; // Email (if available)
|
|
279
|
+
picture?: string; // Avatar URL
|
|
280
|
+
pubkey: string; // Bitcoin public key
|
|
281
|
+
bap?: { // BAP identity (if available)
|
|
282
|
+
idKey: string; // BAP ID
|
|
283
|
+
identity: {
|
|
284
|
+
name?: string;
|
|
285
|
+
alternateName?: string;
|
|
286
|
+
description?: string;
|
|
287
|
+
// ... other BAP profile fields
|
|
288
|
+
};
|
|
289
|
+
};
|
|
290
|
+
};
|
|
291
|
+
access_token: string; // Access token for API calls
|
|
292
|
+
id_token: string; // JWT ID token (OIDC)
|
|
293
|
+
refresh_token?: string; // Refresh token (if issued)
|
|
294
|
+
}
|
|
295
|
+
```
|
|
296
|
+
|
|
89
297
|
## Features
|
|
90
298
|
|
|
91
299
|
- PKCE flow for public clients
|
|
@@ -94,15 +302,7 @@ export const auth = betterAuth({
|
|
|
94
302
|
- Multi-identity wallet support
|
|
95
303
|
- Subscription tier verification via NFT ownership
|
|
96
304
|
- Type-safe with full TypeScript support
|
|
97
|
-
|
|
98
|
-
## Environment Variables
|
|
99
|
-
|
|
100
|
-
```bash
|
|
101
|
-
# Client App
|
|
102
|
-
NEXT_PUBLIC_SIGMA_CLIENT_ID=your-app
|
|
103
|
-
SIGMA_MEMBER_PRIVATE_KEY=your-member-wif
|
|
104
|
-
NEXT_PUBLIC_SIGMA_AUTH_URL=https://auth.sigmaidentity.com
|
|
105
|
-
```
|
|
305
|
+
- Full OIDC compliance with ID tokens
|
|
106
306
|
|
|
107
307
|
## Documentation
|
|
108
308
|
|
package/dist/next/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/next/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,UAAU,WAAW;IACpB,IAAI,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IACzB,OAAO,EAAE;QACR,MAAM,EAAE,MAAM,CAAC;KACf,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IACnC,oGAAoG;IACpG,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,6DAA6D;IAC7D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,6EAA6E;IAC7E,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,yCAAyC;IACzC,YAAY,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,CAAC,EAAE,mBAAmB,IACnD,SAAS,WAAW,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/next/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,UAAU,WAAW;IACpB,IAAI,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IACzB,OAAO,EAAE;QACR,MAAM,EAAE,MAAM,CAAC;KACf,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IACnC,oGAAoG;IACpG,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,6DAA6D;IAC7D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,6EAA6E;IAC7E,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,yCAAyC;IACzC,YAAY,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,CAAC,EAAE,mBAAmB,IACnD,SAAS,WAAW,uBA6GlC;AAED;;;GAGG;AACH,eAAO,MAAM,OAAO,WAAW,CAAC"}
|
package/dist/next/index.js
CHANGED
|
@@ -70,11 +70,12 @@ export function createCallbackHandler(config) {
|
|
|
70
70
|
console.log("[Sigma OAuth Callback] Success:", {
|
|
71
71
|
hasBap: !!result.user.bap,
|
|
72
72
|
name: result.user.name,
|
|
73
|
-
bapId: result.user.bap?.
|
|
73
|
+
bapId: result.user.bap?.id?.substring(0, 20) || "none",
|
|
74
74
|
});
|
|
75
75
|
return Response.json({
|
|
76
76
|
user: result.user,
|
|
77
77
|
access_token: result.access_token,
|
|
78
|
+
id_token: result.id_token,
|
|
78
79
|
refresh_token: result.refresh_token,
|
|
79
80
|
});
|
|
80
81
|
}
|
package/dist/next/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/next/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACN,qBAAqB,GAErB,MAAM,oBAAoB,CAAC;AAwB5B;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,UAAU,qBAAqB,CAAC,MAA4B;IACjE,OAAO,KAAK,EAAE,OAAoB,EAAE,EAAE;QACrC,IAAI,CAAC;YACJ,MAAM,IAAI,GAAG,CAAC,MAAM,OAAO,CAAC,IAAI,EAAE,CAGjC,CAAC;YACF,MAAM,EAAE,IAAI,EAAE,aAAa,EAAE,GAAG,IAAI,CAAC;YAErC,IAAI,CAAC,IAAI,EAAE,CAAC;gBACX,OAAO,QAAQ,CAAC,IAAI,CACnB,EAAE,KAAK,EAAE,4BAA4B,EAAE,EACvC,EAAE,MAAM,EAAE,GAAG,EAAE,CACf,CAAC;YACH,CAAC;YAED,uCAAuC;YACvC,MAAM,gBAAgB,GACrB,MAAM,EAAE,gBAAgB,IAAI,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC;YAClE,IAAI,CAAC,gBAAgB,EAAE,CAAC;gBACvB,OAAO,CAAC,KAAK,CACZ,gEAAgE,CAChE,CAAC;gBACF,OAAO,QAAQ,CAAC,IAAI,CACnB;oBACC,KAAK,EAAE,4BAA4B;oBACnC,OAAO,EAAE,kCAAkC;iBAC3C,EACD,EAAE,MAAM,EAAE,GAAG,EAAE,CACf,CAAC;YACH,CAAC;YAED,MAAM,SAAS,GACd,MAAM,EAAE,SAAS;gBACjB,OAAO,CAAC,GAAG,CAAC,0BAA0B;gBACtC,gCAAgC,CAAC;YAElC,MAAM,QAAQ,GACb,MAAM,EAAE,QAAQ,IAAI,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC;YAC7D,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACf,OAAO,CAAC,KAAK,CACZ,mEAAmE,CACnE,CAAC;gBACF,OAAO,QAAQ,CAAC,IAAI,CACnB,EAAE,KAAK,EAAE,4BAA4B,EAAE,OAAO,EAAE,mBAAmB,EAAE,EACrE,EAAE,MAAM,EAAE,GAAG,EAAE,CACf,CAAC;YACH,CAAC;YAED,MAAM,YAAY,GAAG,MAAM,EAAE,YAAY,IAAI,WAAW,CAAC;YACzD,MAAM,WAAW,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,YAAY,EAAE,CAAC;YAE/D,OAAO,CAAC,GAAG,CAAC,oDAAoD,EAAE;gBACjE,SAAS;gBACT,QAAQ;gBACR,WAAW;aACX,CAAC,CAAC;YAEH,MAAM,MAAM,GAAG,MAAM,qBAAqB,CAAC;gBAC1C,IAAI;gBACJ,WAAW;gBACX,QAAQ;gBACR,gBAAgB;gBAChB,YAAY,EAAE,aAAa;gBAC3B,SAAS;aACT,CAAC,CAAC;YAEH,OAAO,CAAC,GAAG,CAAC,iCAAiC,EAAE;gBAC9C,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG;gBACzB,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI;gBACtB,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/next/index.ts"],"names":[],"mappings":"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"}
|
package/dist/server/index.d.ts
CHANGED
|
@@ -20,6 +20,19 @@ export interface TokenExchangeError {
|
|
|
20
20
|
status?: number;
|
|
21
21
|
endpoint?: string;
|
|
22
22
|
}
|
|
23
|
+
/**
|
|
24
|
+
* OAuth2 token response from the authorization server
|
|
25
|
+
* @see https://www.rfc-editor.org/rfc/rfc6749#section-5.1
|
|
26
|
+
*/
|
|
27
|
+
export interface OAuth2TokenResponse {
|
|
28
|
+
access_token: string;
|
|
29
|
+
token_type: string;
|
|
30
|
+
expires_in: number;
|
|
31
|
+
refresh_token?: string;
|
|
32
|
+
scope: string;
|
|
33
|
+
/** OIDC id_token - only present when openid scope requested */
|
|
34
|
+
id_token?: string;
|
|
35
|
+
}
|
|
23
36
|
/**
|
|
24
37
|
* Exchange OAuth authorization code for access token
|
|
25
38
|
* This function MUST be called server-side only as it requires the member private key
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAGvD,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEnE,MAAM,WAAW,oBAAoB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,mBAAmB;IACnC,IAAI,EAAE,aAAa,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,kBAAkB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,qBAAqB,CAC1C,OAAO,EAAE,oBAAoB,GAC3B,OAAO,CAAC,mBAAmB,CAAC,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAGvD,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEnE,MAAM,WAAW,oBAAoB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,mBAAmB;IACnC,IAAI,EAAE,aAAa,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,kBAAkB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IACnC,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,qBAAqB,CAC1C,OAAO,EAAE,oBAAoB,GAC3B,OAAO,CAAC,mBAAmB,CAAC,CA6F9B"}
|
package/dist/server/index.js
CHANGED
|
@@ -57,7 +57,16 @@ export async function exchangeCodeForTokens(options) {
|
|
|
57
57
|
endpoint: "/api/auth/oauth2/token",
|
|
58
58
|
};
|
|
59
59
|
}
|
|
60
|
-
const tokens =
|
|
60
|
+
const tokens = await tokenResponse.json();
|
|
61
|
+
// Validate that id_token is present (required for OIDC)
|
|
62
|
+
if (!tokens.id_token) {
|
|
63
|
+
throw {
|
|
64
|
+
error: "Missing id_token in token response",
|
|
65
|
+
details: "The authorization server did not return an id_token. Ensure 'openid' scope is included in the authorization request.",
|
|
66
|
+
status: 500,
|
|
67
|
+
endpoint: "/api/auth/oauth2/token",
|
|
68
|
+
};
|
|
69
|
+
}
|
|
61
70
|
// Get user info with the access token
|
|
62
71
|
const userInfoResponse = await fetch(`${issuerUrl}/api/auth/oauth2/userinfo`, {
|
|
63
72
|
headers: {
|
package/dist/server/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AA2C5C;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAC1C,OAA6B;IAE7B,MAAM,EACL,IAAI,EACJ,WAAW,EACX,QAAQ,EACR,gBAAgB,EAChB,YAAY,EACZ,SAAS,GAAG,gCAAgC,GAC5C,GAAG,OAAO,CAAC;IAEZ,2BAA2B;IAC3B,MAAM,UAAU,GAA2B;QAC1C,UAAU,EAAE,oBAAoB;QAChC,IAAI;QACJ,YAAY,EAAE,WAAW;QACzB,SAAS,EAAE,QAAQ;KACnB,CAAC;IAEF,IAAI,YAAY,EAAE,CAAC;QAClB,UAAU,CAAC,aAAa,GAAG,YAAY,CAAC;IACzC,CAAC;IAED,MAAM,WAAW,GAAG,IAAI,eAAe,CAAC,UAAU,CAAC,CAAC,QAAQ,EAAE,CAAC;IAE/D,8CAA8C;IAC9C,wEAAwE;IACxE,MAAM,SAAS,GAAG,YAAY,CAAC;QAC9B,aAAa,EAAE,gBAAgB;QAC/B,WAAW,EAAE,eAAe;QAC5B,IAAI,EAAE,WAAW;KACjB,CAAC,CAAC;IAEH,2BAA2B;IAC3B,MAAM,aAAa,GAAG,MAAM,KAAK,CAAC,GAAG,SAAS,wBAAwB,EAAE;QACvE,MAAM,EAAE,MAAM;QACd,OAAO,EAAE;YACR,cAAc,EAAE,mCAAmC;YACnD,cAAc,EAAE,SAAS;SACzB;QACD,IAAI,EAAE,WAAW;KACjB,CAAC,CAAC;IAEH,IAAI,CAAC,aAAa,CAAC,EAAE,EAAE,CAAC;QACvB,MAAM,SAAS,GAAG,MAAM,aAAa,CAAC,IAAI,EAAE,CAAC;QAC7C,MAAM;YACL,KAAK,EAAE,uBAAuB;YAC9B,OAAO,EAAE,SAAS;YAClB,MAAM,EAAE,aAAa,CAAC,MAAM;YAC5B,QAAQ,EAAE,wBAAwB;SACZ,CAAC;IACzB,CAAC;IAED,MAAM,MAAM,GAAwB,MAAM,aAAa,CAAC,IAAI,EAAE,CAAC;IAE/D,wDAAwD;IACxD,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;QACtB,MAAM;YACL,KAAK,EAAE,oCAAoC;YAC3C,OAAO,EACN,sHAAsH;YACvH,MAAM,EAAE,GAAG;YACX,QAAQ,EAAE,wBAAwB;SACZ,CAAC;IACzB,CAAC;IAED,sCAAsC;IACtC,MAAM,gBAAgB,GAAG,MAAM,KAAK,CACnC,GAAG,SAAS,2BAA2B,EACvC;QACC,OAAO,EAAE;YACR,aAAa,EAAE,UAAU,MAAM,CAAC,YAAY,EAAE;SAC9C;KACD,CACD,CAAC;IAEF,IAAI,CAAC,gBAAgB,CAAC,EAAE,EAAE,CAAC;QAC1B,MAAM,aAAa,GAAG,MAAM,gBAAgB,CAAC,IAAI,EAAE,CAAC;QACpD,MAAM;YACL,KAAK,EAAE,yBAAyB;YAChC,OAAO,EAAE,aAAa;YACtB,MAAM,EAAE,gBAAgB,CAAC,MAAM;YAC/B,QAAQ,EAAE,2BAA2B;SACf,CAAC;IACzB,CAAC;IAED,MAAM,QAAQ,GAAG,CAAC,MAAM,gBAAgB,CAAC,IAAI,EAAE,CAAkB,CAAC;IAElE,OAAO;QACN,IAAI,EAAE,QAAQ;QACd,YAAY,EAAE,MAAM,CAAC,YAAY;QACjC,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,aAAa,EAAE,MAAM,CAAC,aAAa;KACnC,CAAC;AACH,CAAC"}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAExC;;;GAGG;AACH,MAAM,WAAW,UAAU;IAC1B,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAExC;;;GAGG;AACH,MAAM,WAAW,UAAU;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,SAAS,CAAC,EAAE,KAAK,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACpE,QAAQ,CAAC,EAAE;QACV,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACvB,CAAC;IACF,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACvB;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,aAAc,SAAQ,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC;IAEtD,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAGxB,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,UAAU,GAAG,IAAI,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IAClC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,KAAK,GAAG,SAAS,GAAG,YAAY,CAAC;IACzD,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,IAAI,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,OAAO,GAAG,SAAS,CAAC;AAE3D;;GAEG;AACH,MAAM,WAAW,mBAAmB;IACnC,IAAI,EAAE,aAAa,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CAChB"}
|
package/package.json
CHANGED