@solvapay/auth 1.0.8-preview.8 → 1.0.8
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/dist/chunk-ESD73BSC.js +104 -0
- package/dist/index.cjs +71 -42
- package/dist/index.js +1 -1
- package/dist/next-utils.cjs +71 -42
- package/dist/next-utils.d.cts +13 -40
- package/dist/next-utils.d.ts +13 -40
- package/dist/next-utils.js +1 -1
- package/package.json +1 -1
- package/dist/adapter-4HTpALyc.d.cts +0 -32
- package/dist/adapter-4HTpALyc.d.ts +0 -32
- package/dist/adapter-Bl9fq5jF.d.cts +0 -64
- package/dist/adapter-Bl9fq5jF.d.ts +0 -64
- package/dist/chunk-2P77RLPB.js +0 -77
- package/dist/chunk-AIXM4F5E.js +0 -26
- package/dist/chunk-B4VVTQWS.js +0 -77
- package/dist/chunk-IOLE5BMD.js +0 -75
- package/dist/chunk-T3UACNXQ.js +0 -74
- package/dist/src/adapter.d.ts +0 -63
- package/dist/src/adapter.d.ts.map +0 -1
- package/dist/src/adapter.js +0 -8
- package/dist/src/adapter.js.map +0 -1
- package/dist/src/index.d.ts +0 -11
- package/dist/src/index.d.ts.map +0 -1
- package/dist/src/index.js +0 -14
- package/dist/src/index.js.map +0 -1
- package/dist/src/mock.d.ts +0 -30
- package/dist/src/mock.d.ts.map +0 -1
- package/dist/src/mock.js +0 -41
- package/dist/src/mock.js.map +0 -1
- package/dist/src/next-utils.d.ts +0 -159
- package/dist/src/next-utils.d.ts.map +0 -1
- package/dist/src/next-utils.js +0 -222
- package/dist/src/next-utils.js.map +0 -1
- package/dist/src/solvapay.d.ts +0 -65
- package/dist/src/solvapay.d.ts.map +0 -1
- package/dist/src/solvapay.js +0 -143
- package/dist/src/solvapay.js.map +0 -1
- package/dist/src/supabase.d.ts +0 -39
- package/dist/src/supabase.d.ts.map +0 -1
- package/dist/src/supabase.js +0 -62
- package/dist/src/supabase.js.map +0 -1
- package/dist/tsconfig.tsbuildinfo +0 -1
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
// src/next-utils.ts
|
|
2
|
+
function base64UrlDecode(input) {
|
|
3
|
+
const padded = input.replace(/-/g, "+").replace(/_/g, "/");
|
|
4
|
+
const padding = padded.length % 4 === 0 ? "" : "=".repeat(4 - padded.length % 4);
|
|
5
|
+
const base64 = padded + padding;
|
|
6
|
+
if (typeof atob === "function") {
|
|
7
|
+
const binary = atob(base64);
|
|
8
|
+
let result = "";
|
|
9
|
+
for (let i = 0; i < binary.length; i++) {
|
|
10
|
+
result += String.fromCharCode(binary.charCodeAt(i));
|
|
11
|
+
}
|
|
12
|
+
try {
|
|
13
|
+
return decodeURIComponent(escape(result));
|
|
14
|
+
} catch {
|
|
15
|
+
return result;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
const BufferCtor = globalThis.Buffer;
|
|
19
|
+
if (BufferCtor) {
|
|
20
|
+
return BufferCtor.from(base64, "base64").toString("utf-8");
|
|
21
|
+
}
|
|
22
|
+
throw new Error("No base64 decoder available in this runtime");
|
|
23
|
+
}
|
|
24
|
+
function decodeJwtUnverified(token) {
|
|
25
|
+
const parts = token.split(".");
|
|
26
|
+
if (parts.length !== 3) return null;
|
|
27
|
+
try {
|
|
28
|
+
const json = base64UrlDecode(parts[1]);
|
|
29
|
+
const payload = JSON.parse(json);
|
|
30
|
+
if (typeof payload !== "object" || payload === null) return null;
|
|
31
|
+
return payload;
|
|
32
|
+
} catch {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
function extractBearerToken(request) {
|
|
37
|
+
const authHeader = request.headers.get("authorization");
|
|
38
|
+
if (!authHeader || !authHeader.toLowerCase().startsWith("bearer ")) return null;
|
|
39
|
+
const token = authHeader.slice(7).trim();
|
|
40
|
+
return token.length > 0 ? token : null;
|
|
41
|
+
}
|
|
42
|
+
function readEnv(name) {
|
|
43
|
+
const proc = globalThis.process;
|
|
44
|
+
return proc?.env?.[name];
|
|
45
|
+
}
|
|
46
|
+
function isStrictMode() {
|
|
47
|
+
return readEnv("SOLVAPAY_AUTH_STRICT") === "true";
|
|
48
|
+
}
|
|
49
|
+
async function resolveJwtPayload(token, jwtSecret) {
|
|
50
|
+
const secret = jwtSecret || readEnv("SOLVAPAY_JWT_SECRET") || readEnv("SUPABASE_JWT_SECRET");
|
|
51
|
+
if (secret) {
|
|
52
|
+
try {
|
|
53
|
+
const { jwtVerify } = await import("jose");
|
|
54
|
+
const key = new TextEncoder().encode(secret);
|
|
55
|
+
const { payload } = await jwtVerify(token, key, { algorithms: ["HS256"] });
|
|
56
|
+
return payload;
|
|
57
|
+
} catch {
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if (isStrictMode()) return null;
|
|
62
|
+
return decodeJwtUnverified(token);
|
|
63
|
+
}
|
|
64
|
+
function getUserIdFromRequest(request, options) {
|
|
65
|
+
const headerName = options?.headerName || "x-user-id";
|
|
66
|
+
return request.headers.get(headerName);
|
|
67
|
+
}
|
|
68
|
+
async function getUserEmailFromRequest(request, options) {
|
|
69
|
+
const token = extractBearerToken(request);
|
|
70
|
+
if (!token) return null;
|
|
71
|
+
const payload = await resolveJwtPayload(token, options?.jwtSecret);
|
|
72
|
+
if (!payload) return null;
|
|
73
|
+
return typeof payload.email === "string" ? payload.email : null;
|
|
74
|
+
}
|
|
75
|
+
async function getUserNameFromRequest(request, options) {
|
|
76
|
+
const token = extractBearerToken(request);
|
|
77
|
+
if (!token) return null;
|
|
78
|
+
const payload = await resolveJwtPayload(token, options?.jwtSecret);
|
|
79
|
+
if (!payload) return null;
|
|
80
|
+
const metadataFullName = typeof payload.user_metadata?.full_name === "string" ? payload.user_metadata.full_name : null;
|
|
81
|
+
const metadataName = typeof payload.user_metadata?.name === "string" ? payload.user_metadata.name : null;
|
|
82
|
+
const claimName = typeof payload.name === "string" ? payload.name : null;
|
|
83
|
+
return metadataFullName || metadataName || claimName || null;
|
|
84
|
+
}
|
|
85
|
+
function requireUserId(request, options) {
|
|
86
|
+
const headerName = options?.headerName || "x-user-id";
|
|
87
|
+
const errorMessage = options?.errorMessage || "Unauthorized";
|
|
88
|
+
const errorDetails = options?.errorDetails || "User ID not found. Ensure middleware is configured.";
|
|
89
|
+
const userId = request.headers.get(headerName);
|
|
90
|
+
if (!userId) {
|
|
91
|
+
return new Response(JSON.stringify({ error: errorMessage, details: errorDetails }), {
|
|
92
|
+
status: 401,
|
|
93
|
+
headers: { "Content-Type": "application/json" }
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
return userId;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export {
|
|
100
|
+
getUserIdFromRequest,
|
|
101
|
+
getUserEmailFromRequest,
|
|
102
|
+
getUserNameFromRequest,
|
|
103
|
+
requireUserId
|
|
104
|
+
};
|
package/dist/index.cjs
CHANGED
|
@@ -175,59 +175,88 @@ var SolvapayOAuthClient = class {
|
|
|
175
175
|
};
|
|
176
176
|
|
|
177
177
|
// src/next-utils.ts
|
|
178
|
-
function
|
|
179
|
-
const
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
178
|
+
function base64UrlDecode(input) {
|
|
179
|
+
const padded = input.replace(/-/g, "+").replace(/_/g, "/");
|
|
180
|
+
const padding = padded.length % 4 === 0 ? "" : "=".repeat(4 - padded.length % 4);
|
|
181
|
+
const base64 = padded + padding;
|
|
182
|
+
if (typeof atob === "function") {
|
|
183
|
+
const binary = atob(base64);
|
|
184
|
+
let result = "";
|
|
185
|
+
for (let i = 0; i < binary.length; i++) {
|
|
186
|
+
result += String.fromCharCode(binary.charCodeAt(i));
|
|
187
|
+
}
|
|
188
|
+
try {
|
|
189
|
+
return decodeURIComponent(escape(result));
|
|
190
|
+
} catch {
|
|
191
|
+
return result;
|
|
192
|
+
}
|
|
186
193
|
}
|
|
187
|
-
const
|
|
188
|
-
if (
|
|
189
|
-
return
|
|
194
|
+
const BufferCtor = globalThis.Buffer;
|
|
195
|
+
if (BufferCtor) {
|
|
196
|
+
return BufferCtor.from(base64, "base64").toString("utf-8");
|
|
190
197
|
}
|
|
198
|
+
throw new Error("No base64 decoder available in this runtime");
|
|
199
|
+
}
|
|
200
|
+
function decodeJwtUnverified(token) {
|
|
201
|
+
const parts = token.split(".");
|
|
202
|
+
if (parts.length !== 3) return null;
|
|
191
203
|
try {
|
|
192
|
-
const
|
|
193
|
-
const
|
|
194
|
-
if (
|
|
195
|
-
|
|
196
|
-
}
|
|
197
|
-
const secret = new TextEncoder().encode(jwtSecret);
|
|
198
|
-
const { payload } = await jwtVerify(token, secret, {
|
|
199
|
-
algorithms: ["HS256"]
|
|
200
|
-
});
|
|
201
|
-
return payload.email ? String(payload.email) : null;
|
|
204
|
+
const json = base64UrlDecode(parts[1]);
|
|
205
|
+
const payload = JSON.parse(json);
|
|
206
|
+
if (typeof payload !== "object" || payload === null) return null;
|
|
207
|
+
return payload;
|
|
202
208
|
} catch {
|
|
203
209
|
return null;
|
|
204
210
|
}
|
|
205
211
|
}
|
|
206
|
-
|
|
212
|
+
function extractBearerToken(request) {
|
|
207
213
|
const authHeader = request.headers.get("authorization");
|
|
208
|
-
if (!authHeader || !authHeader.startsWith("
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
214
|
+
if (!authHeader || !authHeader.toLowerCase().startsWith("bearer ")) return null;
|
|
215
|
+
const token = authHeader.slice(7).trim();
|
|
216
|
+
return token.length > 0 ? token : null;
|
|
217
|
+
}
|
|
218
|
+
function readEnv(name) {
|
|
219
|
+
const proc = globalThis.process;
|
|
220
|
+
return proc?.env?.[name];
|
|
221
|
+
}
|
|
222
|
+
function isStrictMode() {
|
|
223
|
+
return readEnv("SOLVAPAY_AUTH_STRICT") === "true";
|
|
224
|
+
}
|
|
225
|
+
async function resolveJwtPayload(token, jwtSecret) {
|
|
226
|
+
const secret = jwtSecret || readEnv("SOLVAPAY_JWT_SECRET") || readEnv("SUPABASE_JWT_SECRET");
|
|
227
|
+
if (secret) {
|
|
228
|
+
try {
|
|
229
|
+
const { jwtVerify } = await import("jose");
|
|
230
|
+
const key = new TextEncoder().encode(secret);
|
|
231
|
+
const { payload } = await jwtVerify(token, key, { algorithms: ["HS256"] });
|
|
232
|
+
return payload;
|
|
233
|
+
} catch {
|
|
219
234
|
return null;
|
|
220
235
|
}
|
|
221
|
-
const secret = new TextEncoder().encode(jwtSecret);
|
|
222
|
-
const { payload } = await jwtVerify(token, secret, {
|
|
223
|
-
algorithms: ["HS256"]
|
|
224
|
-
});
|
|
225
|
-
const payloadWithMetadata = payload;
|
|
226
|
-
const name = payloadWithMetadata.user_metadata?.full_name || payloadWithMetadata.user_metadata?.name || payloadWithMetadata.name || null;
|
|
227
|
-
return name ? String(name) : null;
|
|
228
|
-
} catch {
|
|
229
|
-
return null;
|
|
230
236
|
}
|
|
237
|
+
if (isStrictMode()) return null;
|
|
238
|
+
return decodeJwtUnverified(token);
|
|
239
|
+
}
|
|
240
|
+
function getUserIdFromRequest(request, options) {
|
|
241
|
+
const headerName = options?.headerName || "x-user-id";
|
|
242
|
+
return request.headers.get(headerName);
|
|
243
|
+
}
|
|
244
|
+
async function getUserEmailFromRequest(request, options) {
|
|
245
|
+
const token = extractBearerToken(request);
|
|
246
|
+
if (!token) return null;
|
|
247
|
+
const payload = await resolveJwtPayload(token, options?.jwtSecret);
|
|
248
|
+
if (!payload) return null;
|
|
249
|
+
return typeof payload.email === "string" ? payload.email : null;
|
|
250
|
+
}
|
|
251
|
+
async function getUserNameFromRequest(request, options) {
|
|
252
|
+
const token = extractBearerToken(request);
|
|
253
|
+
if (!token) return null;
|
|
254
|
+
const payload = await resolveJwtPayload(token, options?.jwtSecret);
|
|
255
|
+
if (!payload) return null;
|
|
256
|
+
const metadataFullName = typeof payload.user_metadata?.full_name === "string" ? payload.user_metadata.full_name : null;
|
|
257
|
+
const metadataName = typeof payload.user_metadata?.name === "string" ? payload.user_metadata.name : null;
|
|
258
|
+
const claimName = typeof payload.name === "string" ? payload.name : null;
|
|
259
|
+
return metadataFullName || metadataName || claimName || null;
|
|
231
260
|
}
|
|
232
261
|
function requireUserId(request, options) {
|
|
233
262
|
const headerName = options?.headerName || "x-user-id";
|
package/dist/index.js
CHANGED
package/dist/next-utils.cjs
CHANGED
|
@@ -36,59 +36,88 @@ __export(next_utils_exports, {
|
|
|
36
36
|
requireUserId: () => requireUserId
|
|
37
37
|
});
|
|
38
38
|
module.exports = __toCommonJS(next_utils_exports);
|
|
39
|
-
function
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
39
|
+
function base64UrlDecode(input) {
|
|
40
|
+
const padded = input.replace(/-/g, "+").replace(/_/g, "/");
|
|
41
|
+
const padding = padded.length % 4 === 0 ? "" : "=".repeat(4 - padded.length % 4);
|
|
42
|
+
const base64 = padded + padding;
|
|
43
|
+
if (typeof atob === "function") {
|
|
44
|
+
const binary = atob(base64);
|
|
45
|
+
let result = "";
|
|
46
|
+
for (let i = 0; i < binary.length; i++) {
|
|
47
|
+
result += String.fromCharCode(binary.charCodeAt(i));
|
|
48
|
+
}
|
|
49
|
+
try {
|
|
50
|
+
return decodeURIComponent(escape(result));
|
|
51
|
+
} catch {
|
|
52
|
+
return result;
|
|
53
|
+
}
|
|
47
54
|
}
|
|
48
|
-
const
|
|
49
|
-
if (
|
|
50
|
-
return
|
|
55
|
+
const BufferCtor = globalThis.Buffer;
|
|
56
|
+
if (BufferCtor) {
|
|
57
|
+
return BufferCtor.from(base64, "base64").toString("utf-8");
|
|
51
58
|
}
|
|
59
|
+
throw new Error("No base64 decoder available in this runtime");
|
|
60
|
+
}
|
|
61
|
+
function decodeJwtUnverified(token) {
|
|
62
|
+
const parts = token.split(".");
|
|
63
|
+
if (parts.length !== 3) return null;
|
|
52
64
|
try {
|
|
53
|
-
const
|
|
54
|
-
const
|
|
55
|
-
if (
|
|
56
|
-
|
|
57
|
-
}
|
|
58
|
-
const secret = new TextEncoder().encode(jwtSecret);
|
|
59
|
-
const { payload } = await jwtVerify(token, secret, {
|
|
60
|
-
algorithms: ["HS256"]
|
|
61
|
-
});
|
|
62
|
-
return payload.email ? String(payload.email) : null;
|
|
65
|
+
const json = base64UrlDecode(parts[1]);
|
|
66
|
+
const payload = JSON.parse(json);
|
|
67
|
+
if (typeof payload !== "object" || payload === null) return null;
|
|
68
|
+
return payload;
|
|
63
69
|
} catch {
|
|
64
70
|
return null;
|
|
65
71
|
}
|
|
66
72
|
}
|
|
67
|
-
|
|
73
|
+
function extractBearerToken(request) {
|
|
68
74
|
const authHeader = request.headers.get("authorization");
|
|
69
|
-
if (!authHeader || !authHeader.startsWith("
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
75
|
+
if (!authHeader || !authHeader.toLowerCase().startsWith("bearer ")) return null;
|
|
76
|
+
const token = authHeader.slice(7).trim();
|
|
77
|
+
return token.length > 0 ? token : null;
|
|
78
|
+
}
|
|
79
|
+
function readEnv(name) {
|
|
80
|
+
const proc = globalThis.process;
|
|
81
|
+
return proc?.env?.[name];
|
|
82
|
+
}
|
|
83
|
+
function isStrictMode() {
|
|
84
|
+
return readEnv("SOLVAPAY_AUTH_STRICT") === "true";
|
|
85
|
+
}
|
|
86
|
+
async function resolveJwtPayload(token, jwtSecret) {
|
|
87
|
+
const secret = jwtSecret || readEnv("SOLVAPAY_JWT_SECRET") || readEnv("SUPABASE_JWT_SECRET");
|
|
88
|
+
if (secret) {
|
|
89
|
+
try {
|
|
90
|
+
const { jwtVerify } = await import("jose");
|
|
91
|
+
const key = new TextEncoder().encode(secret);
|
|
92
|
+
const { payload } = await jwtVerify(token, key, { algorithms: ["HS256"] });
|
|
93
|
+
return payload;
|
|
94
|
+
} catch {
|
|
80
95
|
return null;
|
|
81
96
|
}
|
|
82
|
-
const secret = new TextEncoder().encode(jwtSecret);
|
|
83
|
-
const { payload } = await jwtVerify(token, secret, {
|
|
84
|
-
algorithms: ["HS256"]
|
|
85
|
-
});
|
|
86
|
-
const payloadWithMetadata = payload;
|
|
87
|
-
const name = payloadWithMetadata.user_metadata?.full_name || payloadWithMetadata.user_metadata?.name || payloadWithMetadata.name || null;
|
|
88
|
-
return name ? String(name) : null;
|
|
89
|
-
} catch {
|
|
90
|
-
return null;
|
|
91
97
|
}
|
|
98
|
+
if (isStrictMode()) return null;
|
|
99
|
+
return decodeJwtUnverified(token);
|
|
100
|
+
}
|
|
101
|
+
function getUserIdFromRequest(request, options) {
|
|
102
|
+
const headerName = options?.headerName || "x-user-id";
|
|
103
|
+
return request.headers.get(headerName);
|
|
104
|
+
}
|
|
105
|
+
async function getUserEmailFromRequest(request, options) {
|
|
106
|
+
const token = extractBearerToken(request);
|
|
107
|
+
if (!token) return null;
|
|
108
|
+
const payload = await resolveJwtPayload(token, options?.jwtSecret);
|
|
109
|
+
if (!payload) return null;
|
|
110
|
+
return typeof payload.email === "string" ? payload.email : null;
|
|
111
|
+
}
|
|
112
|
+
async function getUserNameFromRequest(request, options) {
|
|
113
|
+
const token = extractBearerToken(request);
|
|
114
|
+
if (!token) return null;
|
|
115
|
+
const payload = await resolveJwtPayload(token, options?.jwtSecret);
|
|
116
|
+
if (!payload) return null;
|
|
117
|
+
const metadataFullName = typeof payload.user_metadata?.full_name === "string" ? payload.user_metadata.full_name : null;
|
|
118
|
+
const metadataName = typeof payload.user_metadata?.name === "string" ? payload.user_metadata.name : null;
|
|
119
|
+
const claimName = typeof payload.name === "string" ? payload.name : null;
|
|
120
|
+
return metadataFullName || metadataName || claimName || null;
|
|
92
121
|
}
|
|
93
122
|
function requireUserId(request, options) {
|
|
94
123
|
const headerName = options?.headerName || "x-user-id";
|
package/dist/next-utils.d.cts
CHANGED
|
@@ -44,35 +44,21 @@ declare function getUserIdFromRequest(request: Request, options?: {
|
|
|
44
44
|
headerName?: string;
|
|
45
45
|
}): string | null;
|
|
46
46
|
/**
|
|
47
|
-
* Extract user email from
|
|
47
|
+
* Extract user email from a Bearer JWT in the Authorization header.
|
|
48
48
|
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
49
|
+
* When `SOLVAPAY_JWT_SECRET` or `SUPABASE_JWT_SECRET` is set (or the
|
|
50
|
+
* equivalent `options.jwtSecret`), the token is verified via HS256.
|
|
51
|
+
* Otherwise, the payload is decoded without verification — safe when the
|
|
52
|
+
* platform gateway has already validated the token (e.g. Supabase Edge
|
|
53
|
+
* Functions with `verify_jwt = true`, which is the default). Opt into
|
|
54
|
+
* strict mode with `SOLVAPAY_AUTH_STRICT=true` to disable the
|
|
55
|
+
* unverified-decode fallback.
|
|
54
56
|
*
|
|
55
57
|
* @param request - Request object (works with NextRequest from next/server)
|
|
56
58
|
* @param options - Configuration options
|
|
57
|
-
* @param options.jwtSecret -
|
|
59
|
+
* @param options.jwtSecret - JWT secret (defaults to SOLVAPAY_JWT_SECRET / SUPABASE_JWT_SECRET env var)
|
|
58
60
|
* @returns User email string or null if not found
|
|
59
61
|
*
|
|
60
|
-
* @example
|
|
61
|
-
* ```typescript
|
|
62
|
-
* import { NextRequest, NextResponse } from 'next/server';
|
|
63
|
-
* import { getUserEmailFromRequest } from '@solvapay/auth';
|
|
64
|
-
*
|
|
65
|
-
* export async function GET(request: NextRequest) {
|
|
66
|
-
* const email = await getUserEmailFromRequest(request);
|
|
67
|
-
*
|
|
68
|
-
* if (!email) {
|
|
69
|
-
* return NextResponse.json({ error: 'Email not found' }, { status: 401 });
|
|
70
|
-
* }
|
|
71
|
-
*
|
|
72
|
-
* return NextResponse.json({ email });
|
|
73
|
-
* }
|
|
74
|
-
* ```
|
|
75
|
-
*
|
|
76
62
|
* @see {@link getUserNameFromRequest} for extracting user name
|
|
77
63
|
* @since 1.0.0
|
|
78
64
|
*/
|
|
@@ -80,33 +66,20 @@ declare function getUserEmailFromRequest(request: Request, options?: {
|
|
|
80
66
|
jwtSecret?: string;
|
|
81
67
|
}): Promise<string | null>;
|
|
82
68
|
/**
|
|
83
|
-
* Extract user name from
|
|
69
|
+
* Extract user name from a Bearer JWT in the Authorization header.
|
|
84
70
|
*
|
|
85
|
-
*
|
|
86
|
-
* and extracts the name from user metadata. Checks multiple possible locations:
|
|
71
|
+
* Checks multiple possible locations:
|
|
87
72
|
* - `user_metadata.full_name`
|
|
88
73
|
* - `user_metadata.name`
|
|
89
74
|
* - `name` claim
|
|
90
75
|
*
|
|
91
|
-
*
|
|
76
|
+
* See {@link getUserEmailFromRequest} for the verification/fallback model.
|
|
92
77
|
*
|
|
93
78
|
* @param request - Request object (works with NextRequest from next/server)
|
|
94
79
|
* @param options - Configuration options
|
|
95
|
-
* @param options.jwtSecret -
|
|
80
|
+
* @param options.jwtSecret - JWT secret (defaults to SOLVAPAY_JWT_SECRET / SUPABASE_JWT_SECRET env var)
|
|
96
81
|
* @returns User name string or null if not found
|
|
97
82
|
*
|
|
98
|
-
* @example
|
|
99
|
-
* ```typescript
|
|
100
|
-
* import { NextRequest, NextResponse } from 'next/server';
|
|
101
|
-
* import { getUserNameFromRequest } from '@solvapay/auth';
|
|
102
|
-
*
|
|
103
|
-
* export async function GET(request: NextRequest) {
|
|
104
|
-
* const name = await getUserNameFromRequest(request);
|
|
105
|
-
*
|
|
106
|
-
* return NextResponse.json({ name: name || 'Guest' });
|
|
107
|
-
* }
|
|
108
|
-
* ```
|
|
109
|
-
*
|
|
110
83
|
* @see {@link getUserEmailFromRequest} for extracting user email
|
|
111
84
|
* @since 1.0.0
|
|
112
85
|
*/
|
package/dist/next-utils.d.ts
CHANGED
|
@@ -44,35 +44,21 @@ declare function getUserIdFromRequest(request: Request, options?: {
|
|
|
44
44
|
headerName?: string;
|
|
45
45
|
}): string | null;
|
|
46
46
|
/**
|
|
47
|
-
* Extract user email from
|
|
47
|
+
* Extract user email from a Bearer JWT in the Authorization header.
|
|
48
48
|
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
49
|
+
* When `SOLVAPAY_JWT_SECRET` or `SUPABASE_JWT_SECRET` is set (or the
|
|
50
|
+
* equivalent `options.jwtSecret`), the token is verified via HS256.
|
|
51
|
+
* Otherwise, the payload is decoded without verification — safe when the
|
|
52
|
+
* platform gateway has already validated the token (e.g. Supabase Edge
|
|
53
|
+
* Functions with `verify_jwt = true`, which is the default). Opt into
|
|
54
|
+
* strict mode with `SOLVAPAY_AUTH_STRICT=true` to disable the
|
|
55
|
+
* unverified-decode fallback.
|
|
54
56
|
*
|
|
55
57
|
* @param request - Request object (works with NextRequest from next/server)
|
|
56
58
|
* @param options - Configuration options
|
|
57
|
-
* @param options.jwtSecret -
|
|
59
|
+
* @param options.jwtSecret - JWT secret (defaults to SOLVAPAY_JWT_SECRET / SUPABASE_JWT_SECRET env var)
|
|
58
60
|
* @returns User email string or null if not found
|
|
59
61
|
*
|
|
60
|
-
* @example
|
|
61
|
-
* ```typescript
|
|
62
|
-
* import { NextRequest, NextResponse } from 'next/server';
|
|
63
|
-
* import { getUserEmailFromRequest } from '@solvapay/auth';
|
|
64
|
-
*
|
|
65
|
-
* export async function GET(request: NextRequest) {
|
|
66
|
-
* const email = await getUserEmailFromRequest(request);
|
|
67
|
-
*
|
|
68
|
-
* if (!email) {
|
|
69
|
-
* return NextResponse.json({ error: 'Email not found' }, { status: 401 });
|
|
70
|
-
* }
|
|
71
|
-
*
|
|
72
|
-
* return NextResponse.json({ email });
|
|
73
|
-
* }
|
|
74
|
-
* ```
|
|
75
|
-
*
|
|
76
62
|
* @see {@link getUserNameFromRequest} for extracting user name
|
|
77
63
|
* @since 1.0.0
|
|
78
64
|
*/
|
|
@@ -80,33 +66,20 @@ declare function getUserEmailFromRequest(request: Request, options?: {
|
|
|
80
66
|
jwtSecret?: string;
|
|
81
67
|
}): Promise<string | null>;
|
|
82
68
|
/**
|
|
83
|
-
* Extract user name from
|
|
69
|
+
* Extract user name from a Bearer JWT in the Authorization header.
|
|
84
70
|
*
|
|
85
|
-
*
|
|
86
|
-
* and extracts the name from user metadata. Checks multiple possible locations:
|
|
71
|
+
* Checks multiple possible locations:
|
|
87
72
|
* - `user_metadata.full_name`
|
|
88
73
|
* - `user_metadata.name`
|
|
89
74
|
* - `name` claim
|
|
90
75
|
*
|
|
91
|
-
*
|
|
76
|
+
* See {@link getUserEmailFromRequest} for the verification/fallback model.
|
|
92
77
|
*
|
|
93
78
|
* @param request - Request object (works with NextRequest from next/server)
|
|
94
79
|
* @param options - Configuration options
|
|
95
|
-
* @param options.jwtSecret -
|
|
80
|
+
* @param options.jwtSecret - JWT secret (defaults to SOLVAPAY_JWT_SECRET / SUPABASE_JWT_SECRET env var)
|
|
96
81
|
* @returns User name string or null if not found
|
|
97
82
|
*
|
|
98
|
-
* @example
|
|
99
|
-
* ```typescript
|
|
100
|
-
* import { NextRequest, NextResponse } from 'next/server';
|
|
101
|
-
* import { getUserNameFromRequest } from '@solvapay/auth';
|
|
102
|
-
*
|
|
103
|
-
* export async function GET(request: NextRequest) {
|
|
104
|
-
* const name = await getUserNameFromRequest(request);
|
|
105
|
-
*
|
|
106
|
-
* return NextResponse.json({ name: name || 'Guest' });
|
|
107
|
-
* }
|
|
108
|
-
* ```
|
|
109
|
-
*
|
|
110
83
|
* @see {@link getUserEmailFromRequest} for extracting user email
|
|
111
84
|
* @since 1.0.0
|
|
112
85
|
*/
|
package/dist/next-utils.js
CHANGED
package/package.json
CHANGED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Auth Adapter Interface
|
|
3
|
-
*
|
|
4
|
-
* Defines the contract for authentication adapters that extract user IDs from requests.
|
|
5
|
-
* Implementations should never throw - return null if authentication fails or is missing.
|
|
6
|
-
*/
|
|
7
|
-
/**
|
|
8
|
-
* Request-like object that has headers
|
|
9
|
-
*/
|
|
10
|
-
interface RequestLike {
|
|
11
|
-
headers: Headers | {
|
|
12
|
-
get(name: string): string | null;
|
|
13
|
-
};
|
|
14
|
-
}
|
|
15
|
-
/**
|
|
16
|
-
* Auth adapter interface for extracting user IDs from requests
|
|
17
|
-
*/
|
|
18
|
-
interface AuthAdapter {
|
|
19
|
-
/**
|
|
20
|
-
* Extract the authenticated user ID from a request
|
|
21
|
-
*
|
|
22
|
-
* @param req - Request object or object with headers
|
|
23
|
-
* @returns The user ID string if authenticated, null otherwise
|
|
24
|
-
*
|
|
25
|
-
* @remarks
|
|
26
|
-
* This method should never throw. If authentication fails or is missing,
|
|
27
|
-
* return null and let the caller decide how to handle unauthenticated requests.
|
|
28
|
-
*/
|
|
29
|
-
getUserIdFromRequest(req: Request | RequestLike): Promise<string | null>;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export type { AuthAdapter as A, RequestLike as R };
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Auth Adapter Interface
|
|
3
|
-
*
|
|
4
|
-
* Defines the contract for authentication adapters that extract user IDs from requests.
|
|
5
|
-
* Implementations should never throw - return null if authentication fails or is missing.
|
|
6
|
-
*/
|
|
7
|
-
/**
|
|
8
|
-
* Request-like object that has headers
|
|
9
|
-
*/
|
|
10
|
-
interface RequestLike {
|
|
11
|
-
headers: Headers | {
|
|
12
|
-
get(name: string): string | null;
|
|
13
|
-
};
|
|
14
|
-
}
|
|
15
|
-
/**
|
|
16
|
-
* Auth adapter interface for extracting user IDs from requests
|
|
17
|
-
*/
|
|
18
|
-
interface AuthAdapter {
|
|
19
|
-
/**
|
|
20
|
-
* Extract the authenticated user ID from a request
|
|
21
|
-
*
|
|
22
|
-
* @param req - Request object or object with headers
|
|
23
|
-
* @returns The user ID string if authenticated, null otherwise
|
|
24
|
-
*
|
|
25
|
-
* @remarks
|
|
26
|
-
* This method should never throw. If authentication fails or is missing,
|
|
27
|
-
* return null and let the caller decide how to handle unauthenticated requests.
|
|
28
|
-
*/
|
|
29
|
-
getUserIdFromRequest(req: Request | RequestLike): Promise<string | null>;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export type { AuthAdapter as A, RequestLike as R };
|