@cimplify/sdk 0.53.0 → 0.55.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/dist/advanced.d.mts +1 -1
- package/dist/advanced.d.ts +1 -1
- package/dist/advanced.js +20 -20
- package/dist/advanced.mjs +1 -1
- package/dist/{chunk-EJUKGJTZ.js → chunk-6W3AH4QW.js} +2 -2
- package/dist/{chunk-NEK7CVE2.mjs → chunk-F4WS3OIF.mjs} +1 -1
- package/dist/{chunk-B3Y4C4A7.mjs → chunk-I4IXPQIX.mjs} +7 -4
- package/dist/{chunk-YJLOOC3L.js → chunk-JGBDWEPJ.js} +7 -4
- package/dist/chunk-JYPLT56O.js +272 -0
- package/dist/{chunk-IJ32BXKZ.js → chunk-MW7ICTVK.js} +35 -35
- package/dist/{chunk-6QZQQRBB.mjs → chunk-SQ7U3BWY.mjs} +1 -1
- package/dist/chunk-XYI4NXWG.mjs +259 -0
- package/dist/{client-D1Gknspz.d.mts → client-Bhvlelij.d.mts} +1 -1
- package/dist/{client-Bj2apl_y.d.mts → client-DKg-5OWu.d.mts} +16 -1
- package/dist/{client-306peWZ0.d.ts → client-Dfg_hmkP.d.ts} +16 -1
- package/dist/{client-C2bKMy5g.d.ts → client-DlGJqSDd.d.ts} +1 -1
- package/dist/index.d.mts +18 -3
- package/dist/index.d.ts +18 -3
- package/dist/index.js +160 -72
- package/dist/index.mjs +91 -3
- package/dist/react.d.mts +52 -5
- package/dist/react.d.ts +52 -5
- package/dist/react.js +592 -512
- package/dist/react.mjs +136 -58
- package/dist/server.d.mts +59 -35
- package/dist/server.d.ts +59 -35
- package/dist/server.js +160 -79
- package/dist/server.mjs +153 -78
- package/dist/{ads-C2c2Aald.d.mts → sign-in-TL01-awQ.d.mts} +17 -1
- package/dist/{ads-C2c2Aald.d.ts → sign-in-TL01-awQ.d.ts} +17 -1
- package/dist/styles.css +1 -1
- package/dist/testing/suite.d.mts +2 -2
- package/dist/testing/suite.d.ts +2 -2
- package/dist/testing/suite.js +22 -22
- package/dist/testing/suite.mjs +3 -3
- package/dist/testing.d.mts +2 -2
- package/dist/testing.d.ts +2 -2
- package/dist/testing.js +78 -78
- package/dist/testing.mjs +4 -4
- package/package.json +2 -1
- package/registry/account.json +1 -1
- package/dist/chunk-MN4PNKJA.js +0 -129
- package/dist/chunk-NRDRVZ62.mjs +0 -119
package/dist/server.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { ac as CimplifyClient } from './client-
|
|
2
|
-
export { J as CacheOptions, c7 as ReadRequestOptions, ct as Result } from './client-
|
|
1
|
+
import { ac as CimplifyClient } from './client-Dfg_hmkP.js';
|
|
2
|
+
export { J as CacheOptions, c7 as ReadRequestOptions, ct as Result } from './client-Dfg_hmkP.js';
|
|
3
3
|
export { Q as Category, T as CimplifyError, U as Collection, aX as Product, b9 as ProductWithDetails } from './product-B_kS4Oxa.js';
|
|
4
|
+
import { JWTVerifyResult } from 'jose';
|
|
4
5
|
import './payment-sn-yGL7v.js';
|
|
5
6
|
|
|
6
7
|
interface ServerClientOptions {
|
|
@@ -145,26 +146,26 @@ type CacheLifeDefault = typeof CACHE_LIFE_DEFAULT;
|
|
|
145
146
|
type CacheLifeProbe = typeof CACHE_LIFE_PROBE;
|
|
146
147
|
|
|
147
148
|
/** Next 16 cacheLife profile — a built-in name (`'max'`/`'hours'`/…) or `{expire: secs}`. */
|
|
148
|
-
type RevalidateProfile
|
|
149
|
+
type RevalidateProfile = string | {
|
|
149
150
|
expire: number;
|
|
150
151
|
};
|
|
151
|
-
declare function revalidateProducts(profile?: RevalidateProfile
|
|
152
|
-
declare function revalidateProduct(id: string, profile?: RevalidateProfile
|
|
153
|
-
declare function revalidateCategories(profile?: RevalidateProfile
|
|
154
|
-
declare function revalidateCategory(id: string, profile?: RevalidateProfile
|
|
155
|
-
declare function revalidateCollections(profile?: RevalidateProfile
|
|
156
|
-
declare function revalidateCollection(id: string, profile?: RevalidateProfile
|
|
157
|
-
declare function revalidateBusiness(profile?: RevalidateProfile
|
|
158
|
-
declare function revalidateBrand(profile?: RevalidateProfile
|
|
159
|
-
declare function revalidateLocations(profile?: RevalidateProfile
|
|
160
|
-
declare function revalidateLocation(id: string, profile?: RevalidateProfile
|
|
161
|
-
declare function revalidatePricing(profile?: RevalidateProfile
|
|
162
|
-
declare function revalidateAddOns(profile?: RevalidateProfile
|
|
163
|
-
declare function revalidateAddOn(id: string, profile?: RevalidateProfile
|
|
164
|
-
declare function revalidateSubscriptions(profile?: RevalidateProfile
|
|
165
|
-
declare function revalidateSubscription(id: string, profile?: RevalidateProfile
|
|
166
|
-
declare function revalidateStock(productId?: string, profile?: RevalidateProfile
|
|
167
|
-
declare function revalidateByTag(tag: string, profile?: RevalidateProfile
|
|
152
|
+
declare function revalidateProducts(profile?: RevalidateProfile): Promise<void>;
|
|
153
|
+
declare function revalidateProduct(id: string, profile?: RevalidateProfile): Promise<void>;
|
|
154
|
+
declare function revalidateCategories(profile?: RevalidateProfile): Promise<void>;
|
|
155
|
+
declare function revalidateCategory(id: string, profile?: RevalidateProfile): Promise<void>;
|
|
156
|
+
declare function revalidateCollections(profile?: RevalidateProfile): Promise<void>;
|
|
157
|
+
declare function revalidateCollection(id: string, profile?: RevalidateProfile): Promise<void>;
|
|
158
|
+
declare function revalidateBusiness(profile?: RevalidateProfile): Promise<void>;
|
|
159
|
+
declare function revalidateBrand(profile?: RevalidateProfile): Promise<void>;
|
|
160
|
+
declare function revalidateLocations(profile?: RevalidateProfile): Promise<void>;
|
|
161
|
+
declare function revalidateLocation(id: string, profile?: RevalidateProfile): Promise<void>;
|
|
162
|
+
declare function revalidatePricing(profile?: RevalidateProfile): Promise<void>;
|
|
163
|
+
declare function revalidateAddOns(profile?: RevalidateProfile): Promise<void>;
|
|
164
|
+
declare function revalidateAddOn(id: string, profile?: RevalidateProfile): Promise<void>;
|
|
165
|
+
declare function revalidateSubscriptions(profile?: RevalidateProfile): Promise<void>;
|
|
166
|
+
declare function revalidateSubscription(id: string, profile?: RevalidateProfile): Promise<void>;
|
|
167
|
+
declare function revalidateStock(productId?: string, profile?: RevalidateProfile): Promise<void>;
|
|
168
|
+
declare function revalidateByTag(tag: string, profile?: RevalidateProfile): Promise<void>;
|
|
168
169
|
|
|
169
170
|
declare function updateProducts(): Promise<void>;
|
|
170
171
|
declare function updateProduct(id: string): Promise<void>;
|
|
@@ -185,20 +186,43 @@ declare function updateStock(productId?: string): Promise<void>;
|
|
|
185
186
|
declare function updateByTag(tag: string): Promise<void>;
|
|
186
187
|
declare function refreshPage(): Promise<void>;
|
|
187
188
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
189
|
+
interface OidcConfig {
|
|
190
|
+
authUrl?: string;
|
|
191
|
+
clientId: string;
|
|
192
|
+
cookieName?: string;
|
|
193
|
+
cookieDomain?: string;
|
|
194
|
+
}
|
|
195
|
+
interface CimplifySession {
|
|
196
|
+
sub: string;
|
|
197
|
+
name?: string;
|
|
198
|
+
email?: string;
|
|
199
|
+
emailVerified?: boolean;
|
|
200
|
+
phoneNumber?: string;
|
|
201
|
+
phoneNumberVerified?: boolean;
|
|
202
|
+
exp: number;
|
|
203
|
+
iat: number;
|
|
204
|
+
}
|
|
205
|
+
interface CodeExchangeOptions extends OidcConfig {
|
|
206
|
+
code: string;
|
|
207
|
+
codeVerifier: string;
|
|
208
|
+
redirectUri: string;
|
|
209
|
+
}
|
|
210
|
+
interface CodeExchangeResult {
|
|
211
|
+
accessToken: string;
|
|
212
|
+
idToken?: string;
|
|
213
|
+
refreshToken?: string;
|
|
214
|
+
expiresIn: number;
|
|
215
|
+
scope: string;
|
|
216
|
+
}
|
|
217
|
+
declare function exchangeCode(opts: CodeExchangeOptions): Promise<CodeExchangeResult>;
|
|
218
|
+
declare function verifyIdToken(cfg: OidcConfig, idToken: string): Promise<JWTVerifyResult>;
|
|
219
|
+
declare function buildSessionCookie(cfg: OidcConfig, idToken: string, maxAgeSeconds: number): string;
|
|
220
|
+
declare function buildSignoutCookie(cfg: OidcConfig): string;
|
|
221
|
+
interface CallbackHandlerOptions extends OidcConfig {
|
|
222
|
+
redirectUri: string;
|
|
201
223
|
}
|
|
202
|
-
declare function
|
|
224
|
+
declare function handleOidcCallback(req: Request, opts: CallbackHandlerOptions): Promise<Response>;
|
|
225
|
+
declare function handleSessionRequest(req: Request, cfg: OidcConfig): Promise<Response>;
|
|
226
|
+
declare function getSessionFromCookieHeader(cfg: OidcConfig, cookieHeader: string | null | undefined): Promise<CimplifySession | null>;
|
|
203
227
|
|
|
204
|
-
export { CACHE_LIFE_DEFAULT, CACHE_LIFE_PROBE, type CacheLifeDefault, type CacheLifeProbe, CimplifyClient, type
|
|
228
|
+
export { CACHE_LIFE_DEFAULT, CACHE_LIFE_PROBE, type CacheLifeDefault, type CacheLifeProbe, type CallbackHandlerOptions, CimplifyClient, type CimplifySession, type CodeExchangeOptions, type CodeExchangeResult, type OidcConfig, type RevalidateProfile, type ServerClientOptions, buildSessionCookie, buildSignoutCookie, exchangeCode, getServerClient, getSessionFromCookieHeader, handleOidcCallback, handleSessionRequest, refreshPage, revalidateAddOn, revalidateAddOns, revalidateBrand, revalidateBusiness, revalidateByTag, revalidateCategories, revalidateCategory, revalidateCollection, revalidateCollections, revalidateLocation, revalidateLocations, revalidatePricing, revalidateProduct, revalidateProducts, revalidateStock, revalidateSubscription, revalidateSubscriptions, tags, updateAddOn, updateAddOns, updateBrand, updateBusiness, updateByTag, updateCategories, updateCategory, updateCollection, updateCollections, updateLocation, updateLocations, updatePricing, updateProduct, updateProducts, updateStock, updateSubscription, updateSubscriptions, verifyIdToken };
|
package/dist/server.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
require('./chunk-
|
|
3
|
+
var chunkMW7ICTVK_js = require('./chunk-MW7ICTVK.js');
|
|
4
|
+
require('./chunk-JGBDWEPJ.js');
|
|
5
5
|
require('./chunk-7Y2O3E4D.js');
|
|
6
6
|
var chunkXA3ZNR75_js = require('./chunk-XA3ZNR75.js');
|
|
7
7
|
require('./chunk-OWW5GUSB.js');
|
|
8
8
|
var react = require('react');
|
|
9
|
+
var jose = require('jose');
|
|
9
10
|
|
|
10
11
|
var DEFAULT_PROD_URL = "https://storefronts.cimplify.io";
|
|
11
12
|
var DEFAULT_DEV_URL = "http://127.0.0.1:8787";
|
|
@@ -25,7 +26,7 @@ function readEnv(...keys) {
|
|
|
25
26
|
var getServerClient = react.cache((opts = {}) => {
|
|
26
27
|
const baseUrl = opts.apiUrl ?? readEnv("CIMPLIFY_API_URL", "NEXT_PUBLIC_CIMPLIFY_API_URL") ?? defaultBaseUrl();
|
|
27
28
|
const publicKey = opts.secretKey ?? readEnv("CIMPLIFY_SECRET_KEY", "NEXT_PUBLIC_CIMPLIFY_PUBLIC_KEY") ?? "mock-dev";
|
|
28
|
-
const client =
|
|
29
|
+
const client = chunkMW7ICTVK_js.createCimplifyClient({
|
|
29
30
|
baseUrl,
|
|
30
31
|
publicKey,
|
|
31
32
|
suppressPublicKeyWarning: true
|
|
@@ -233,90 +234,164 @@ async function refreshPage() {
|
|
|
233
234
|
const fn = await getRefresh();
|
|
234
235
|
fn();
|
|
235
236
|
}
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
var
|
|
239
|
-
var
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
const
|
|
248
|
-
|
|
249
|
-
if (!
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
237
|
+
var DEFAULT_AUTH_URL = "https://auth.cimplify.io";
|
|
238
|
+
var SESSION_COOKIE = "cimplify_session";
|
|
239
|
+
var discoveryCache = /* @__PURE__ */ new Map();
|
|
240
|
+
var jwksCache = /* @__PURE__ */ new Map();
|
|
241
|
+
function authUrl(cfg) {
|
|
242
|
+
return (cfg.authUrl ?? DEFAULT_AUTH_URL).replace(/\/$/, "");
|
|
243
|
+
}
|
|
244
|
+
function cookieName(cfg) {
|
|
245
|
+
return cfg.cookieName ?? SESSION_COOKIE;
|
|
246
|
+
}
|
|
247
|
+
async function discovery(cfg) {
|
|
248
|
+
const base = authUrl(cfg);
|
|
249
|
+
let p = discoveryCache.get(base);
|
|
250
|
+
if (!p) {
|
|
251
|
+
p = fetch(`${base}/.well-known/openid-configuration`, {
|
|
252
|
+
next: { revalidate: 3600 }
|
|
253
|
+
}).then((r) => {
|
|
254
|
+
if (!r.ok) throw new Error(`oidc discovery failed: ${r.status}`);
|
|
255
|
+
return r.json();
|
|
256
|
+
});
|
|
257
|
+
discoveryCache.set(base, p);
|
|
258
|
+
}
|
|
259
|
+
return p;
|
|
260
|
+
}
|
|
261
|
+
async function jwks(cfg) {
|
|
262
|
+
const doc = await discovery(cfg);
|
|
263
|
+
let set = jwksCache.get(doc.jwks_uri);
|
|
264
|
+
if (!set) {
|
|
265
|
+
set = jose.createRemoteJWKSet(new URL(doc.jwks_uri));
|
|
266
|
+
jwksCache.set(doc.jwks_uri, set);
|
|
254
267
|
}
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
268
|
+
return { set, issuer: doc.issuer };
|
|
269
|
+
}
|
|
270
|
+
async function exchangeCode(opts) {
|
|
271
|
+
const doc = await discovery(opts);
|
|
272
|
+
const body = new URLSearchParams({
|
|
273
|
+
grant_type: "authorization_code",
|
|
274
|
+
code: opts.code,
|
|
275
|
+
code_verifier: opts.codeVerifier,
|
|
276
|
+
redirect_uri: opts.redirectUri,
|
|
277
|
+
client_id: opts.clientId
|
|
278
|
+
});
|
|
279
|
+
const res = await fetch(doc.token_endpoint, {
|
|
280
|
+
method: "POST",
|
|
281
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
282
|
+
body: body.toString()
|
|
283
|
+
});
|
|
284
|
+
if (!res.ok) {
|
|
285
|
+
const text = await res.text().catch(() => "");
|
|
286
|
+
throw new Error(`token exchange failed (${res.status}): ${text}`);
|
|
258
287
|
}
|
|
259
|
-
|
|
288
|
+
const payload = await res.json();
|
|
289
|
+
return {
|
|
290
|
+
accessToken: payload.access_token,
|
|
291
|
+
idToken: payload.id_token,
|
|
292
|
+
refreshToken: payload.refresh_token,
|
|
293
|
+
expiresIn: payload.expires_in,
|
|
294
|
+
scope: payload.scope
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
async function verifyIdToken(cfg, idToken) {
|
|
298
|
+
const { set, issuer } = await jwks(cfg);
|
|
299
|
+
return jose.jwtVerify(idToken, set, {
|
|
300
|
+
issuer,
|
|
301
|
+
audience: cfg.clientId
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
function payloadToSession(payload) {
|
|
305
|
+
return {
|
|
306
|
+
sub: String(payload.sub ?? ""),
|
|
307
|
+
name: payload.name,
|
|
308
|
+
email: payload.email,
|
|
309
|
+
emailVerified: payload.email_verified,
|
|
310
|
+
phoneNumber: payload.phone_number,
|
|
311
|
+
phoneNumberVerified: payload.phone_number_verified,
|
|
312
|
+
exp: Number(payload.exp ?? 0),
|
|
313
|
+
iat: Number(payload.iat ?? 0)
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
function buildSessionCookie(cfg, idToken, maxAgeSeconds) {
|
|
317
|
+
const name = cookieName(cfg);
|
|
318
|
+
const parts = [
|
|
319
|
+
`${name}=${idToken}`,
|
|
320
|
+
"Path=/",
|
|
321
|
+
"HttpOnly",
|
|
322
|
+
"Secure",
|
|
323
|
+
"SameSite=Lax",
|
|
324
|
+
`Max-Age=${maxAgeSeconds}`
|
|
325
|
+
];
|
|
326
|
+
if (cfg.cookieDomain) parts.push(`Domain=${cfg.cookieDomain}`);
|
|
327
|
+
return parts.join("; ");
|
|
328
|
+
}
|
|
329
|
+
function buildSignoutCookie(cfg) {
|
|
330
|
+
const name = cookieName(cfg);
|
|
331
|
+
const parts = [`${name}=`, "Path=/", "HttpOnly", "Secure", "SameSite=Lax", "Max-Age=0"];
|
|
332
|
+
if (cfg.cookieDomain) parts.push(`Domain=${cfg.cookieDomain}`);
|
|
333
|
+
return parts.join("; ");
|
|
334
|
+
}
|
|
335
|
+
async function handleOidcCallback(req, opts) {
|
|
336
|
+
let body;
|
|
260
337
|
try {
|
|
261
|
-
|
|
338
|
+
body = await req.json();
|
|
262
339
|
} catch {
|
|
263
|
-
return
|
|
340
|
+
return Response.json({ error: "invalid_json" }, { status: 400 });
|
|
264
341
|
}
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
const profile = parseProfile(parsed.profile) ?? options.defaultProfile ?? DEFAULT_PROFILE2;
|
|
268
|
-
const revalidate2 = options.revalidateTag ?? await loadRevalidateTag();
|
|
269
|
-
for (const tag of tags2) revalidate2(tag, profile);
|
|
270
|
-
return Response.json({ ok: true, revalidated: tags2.length, profile });
|
|
271
|
-
}
|
|
272
|
-
function parseProfile(raw) {
|
|
273
|
-
if (typeof raw === "string" && raw.length > 0) return raw;
|
|
274
|
-
if (raw && typeof raw === "object" && "expire" in raw && typeof raw.expire === "number") {
|
|
275
|
-
return { expire: raw.expire };
|
|
342
|
+
if (!body.code || !body.codeVerifier) {
|
|
343
|
+
return Response.json({ error: "missing_code_or_verifier" }, { status: 400 });
|
|
276
344
|
}
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
)
|
|
288
|
-
|
|
289
|
-
return cachedRevalidateTag;
|
|
290
|
-
}
|
|
291
|
-
async function verifyHmac(secret, payload, signatureHeader) {
|
|
292
|
-
if (!signatureHeader.startsWith(SIGNATURE_PREFIX)) return false;
|
|
293
|
-
const providedBytes = hexToBytes(signatureHeader.slice(SIGNATURE_PREFIX.length));
|
|
294
|
-
if (!providedBytes) return false;
|
|
295
|
-
const enc = new TextEncoder();
|
|
296
|
-
const key = await crypto.subtle.importKey(
|
|
297
|
-
"raw",
|
|
298
|
-
enc.encode(secret),
|
|
299
|
-
{ name: "HMAC", hash: "SHA-256" },
|
|
300
|
-
false,
|
|
301
|
-
["verify"]
|
|
302
|
-
);
|
|
303
|
-
return crypto.subtle.verify("HMAC", key, providedBytes, enc.encode(payload));
|
|
304
|
-
}
|
|
305
|
-
function hexToBytes(hex) {
|
|
306
|
-
if (hex.length % 2 !== 0 || !/^[0-9a-f]+$/i.test(hex)) return null;
|
|
307
|
-
const buf = new ArrayBuffer(hex.length / 2);
|
|
308
|
-
const out = new Uint8Array(buf);
|
|
309
|
-
for (let i = 0; i < hex.length; i += 2) {
|
|
310
|
-
out[i / 2] = Number.parseInt(hex.slice(i, i + 2), 16);
|
|
345
|
+
let tokens;
|
|
346
|
+
try {
|
|
347
|
+
tokens = await exchangeCode({
|
|
348
|
+
...opts,
|
|
349
|
+
code: body.code,
|
|
350
|
+
codeVerifier: body.codeVerifier
|
|
351
|
+
});
|
|
352
|
+
} catch (e) {
|
|
353
|
+
return Response.json({ error: "exchange_failed", detail: String(e) }, { status: 400 });
|
|
354
|
+
}
|
|
355
|
+
if (!tokens.idToken) {
|
|
356
|
+
return Response.json({ error: "missing_id_token" }, { status: 400 });
|
|
311
357
|
}
|
|
312
|
-
|
|
358
|
+
try {
|
|
359
|
+
await verifyIdToken(opts, tokens.idToken);
|
|
360
|
+
} catch (e) {
|
|
361
|
+
return Response.json({ error: "id_token_invalid", detail: String(e) }, { status: 401 });
|
|
362
|
+
}
|
|
363
|
+
const cookie = buildSessionCookie(opts, tokens.idToken, tokens.expiresIn);
|
|
364
|
+
return new Response(JSON.stringify({ ok: true }), {
|
|
365
|
+
status: 200,
|
|
366
|
+
headers: { "Content-Type": "application/json", "Set-Cookie": cookie }
|
|
367
|
+
});
|
|
313
368
|
}
|
|
314
|
-
function
|
|
315
|
-
const
|
|
316
|
-
|
|
369
|
+
async function handleSessionRequest(req, cfg) {
|
|
370
|
+
const session = await getSessionFromCookieHeader(cfg, req.headers.get("cookie"));
|
|
371
|
+
if (!session) {
|
|
372
|
+
return new Response(JSON.stringify({ sub: null }), {
|
|
373
|
+
status: 200,
|
|
374
|
+
headers: { "Content-Type": "application/json", "Cache-Control": "no-store" }
|
|
375
|
+
});
|
|
376
|
+
}
|
|
377
|
+
return new Response(JSON.stringify(session), {
|
|
378
|
+
status: 200,
|
|
379
|
+
headers: { "Content-Type": "application/json", "Cache-Control": "no-store" }
|
|
380
|
+
});
|
|
317
381
|
}
|
|
318
|
-
function
|
|
319
|
-
|
|
382
|
+
async function getSessionFromCookieHeader(cfg, cookieHeader) {
|
|
383
|
+
if (!cookieHeader) return null;
|
|
384
|
+
const name = cookieName(cfg);
|
|
385
|
+
const match = cookieHeader.split(/;\s*/).find((p) => p.startsWith(`${name}=`));
|
|
386
|
+
if (!match) return null;
|
|
387
|
+
const token = match.slice(name.length + 1);
|
|
388
|
+
if (!token) return null;
|
|
389
|
+
try {
|
|
390
|
+
const { payload } = await verifyIdToken(cfg, token);
|
|
391
|
+
return payloadToSession(payload);
|
|
392
|
+
} catch {
|
|
393
|
+
return null;
|
|
394
|
+
}
|
|
320
395
|
}
|
|
321
396
|
|
|
322
397
|
Object.defineProperty(exports, "CimplifyError", {
|
|
@@ -325,7 +400,13 @@ Object.defineProperty(exports, "CimplifyError", {
|
|
|
325
400
|
});
|
|
326
401
|
exports.CACHE_LIFE_DEFAULT = CACHE_LIFE_DEFAULT;
|
|
327
402
|
exports.CACHE_LIFE_PROBE = CACHE_LIFE_PROBE;
|
|
403
|
+
exports.buildSessionCookie = buildSessionCookie;
|
|
404
|
+
exports.buildSignoutCookie = buildSignoutCookie;
|
|
405
|
+
exports.exchangeCode = exchangeCode;
|
|
328
406
|
exports.getServerClient = getServerClient;
|
|
407
|
+
exports.getSessionFromCookieHeader = getSessionFromCookieHeader;
|
|
408
|
+
exports.handleOidcCallback = handleOidcCallback;
|
|
409
|
+
exports.handleSessionRequest = handleSessionRequest;
|
|
329
410
|
exports.refreshPage = refreshPage;
|
|
330
411
|
exports.revalidateAddOn = revalidateAddOn;
|
|
331
412
|
exports.revalidateAddOns = revalidateAddOns;
|
|
@@ -341,7 +422,6 @@ exports.revalidateLocations = revalidateLocations;
|
|
|
341
422
|
exports.revalidatePricing = revalidatePricing;
|
|
342
423
|
exports.revalidateProduct = revalidateProduct;
|
|
343
424
|
exports.revalidateProducts = revalidateProducts;
|
|
344
|
-
exports.revalidateRouteHandler = revalidateRouteHandler;
|
|
345
425
|
exports.revalidateStock = revalidateStock;
|
|
346
426
|
exports.revalidateSubscription = revalidateSubscription;
|
|
347
427
|
exports.revalidateSubscriptions = revalidateSubscriptions;
|
|
@@ -363,3 +443,4 @@ exports.updateProducts = updateProducts;
|
|
|
363
443
|
exports.updateStock = updateStock;
|
|
364
444
|
exports.updateSubscription = updateSubscription;
|
|
365
445
|
exports.updateSubscriptions = updateSubscriptions;
|
|
446
|
+
exports.verifyIdToken = verifyIdToken;
|
package/dist/server.mjs
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { createCimplifyClient } from './chunk-
|
|
2
|
-
import './chunk-
|
|
1
|
+
import { createCimplifyClient } from './chunk-SQ7U3BWY.mjs';
|
|
2
|
+
import './chunk-I4IXPQIX.mjs';
|
|
3
3
|
import './chunk-TD3AY34U.mjs';
|
|
4
4
|
export { CimplifyError } from './chunk-AMZXALF6.mjs';
|
|
5
5
|
import './chunk-3G6RQLXK.mjs';
|
|
6
6
|
import { cache } from 'react';
|
|
7
|
+
import { jwtVerify, createRemoteJWKSet } from 'jose';
|
|
7
8
|
|
|
8
9
|
var DEFAULT_PROD_URL = "https://storefronts.cimplify.io";
|
|
9
10
|
var DEFAULT_DEV_URL = "http://127.0.0.1:8787";
|
|
@@ -231,90 +232,164 @@ async function refreshPage() {
|
|
|
231
232
|
const fn = await getRefresh();
|
|
232
233
|
fn();
|
|
233
234
|
}
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
var
|
|
237
|
-
var
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
const
|
|
246
|
-
|
|
247
|
-
if (!
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
235
|
+
var DEFAULT_AUTH_URL = "https://auth.cimplify.io";
|
|
236
|
+
var SESSION_COOKIE = "cimplify_session";
|
|
237
|
+
var discoveryCache = /* @__PURE__ */ new Map();
|
|
238
|
+
var jwksCache = /* @__PURE__ */ new Map();
|
|
239
|
+
function authUrl(cfg) {
|
|
240
|
+
return (cfg.authUrl ?? DEFAULT_AUTH_URL).replace(/\/$/, "");
|
|
241
|
+
}
|
|
242
|
+
function cookieName(cfg) {
|
|
243
|
+
return cfg.cookieName ?? SESSION_COOKIE;
|
|
244
|
+
}
|
|
245
|
+
async function discovery(cfg) {
|
|
246
|
+
const base = authUrl(cfg);
|
|
247
|
+
let p = discoveryCache.get(base);
|
|
248
|
+
if (!p) {
|
|
249
|
+
p = fetch(`${base}/.well-known/openid-configuration`, {
|
|
250
|
+
next: { revalidate: 3600 }
|
|
251
|
+
}).then((r) => {
|
|
252
|
+
if (!r.ok) throw new Error(`oidc discovery failed: ${r.status}`);
|
|
253
|
+
return r.json();
|
|
254
|
+
});
|
|
255
|
+
discoveryCache.set(base, p);
|
|
256
|
+
}
|
|
257
|
+
return p;
|
|
258
|
+
}
|
|
259
|
+
async function jwks(cfg) {
|
|
260
|
+
const doc = await discovery(cfg);
|
|
261
|
+
let set = jwksCache.get(doc.jwks_uri);
|
|
262
|
+
if (!set) {
|
|
263
|
+
set = createRemoteJWKSet(new URL(doc.jwks_uri));
|
|
264
|
+
jwksCache.set(doc.jwks_uri, set);
|
|
252
265
|
}
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
266
|
+
return { set, issuer: doc.issuer };
|
|
267
|
+
}
|
|
268
|
+
async function exchangeCode(opts) {
|
|
269
|
+
const doc = await discovery(opts);
|
|
270
|
+
const body = new URLSearchParams({
|
|
271
|
+
grant_type: "authorization_code",
|
|
272
|
+
code: opts.code,
|
|
273
|
+
code_verifier: opts.codeVerifier,
|
|
274
|
+
redirect_uri: opts.redirectUri,
|
|
275
|
+
client_id: opts.clientId
|
|
276
|
+
});
|
|
277
|
+
const res = await fetch(doc.token_endpoint, {
|
|
278
|
+
method: "POST",
|
|
279
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
280
|
+
body: body.toString()
|
|
281
|
+
});
|
|
282
|
+
if (!res.ok) {
|
|
283
|
+
const text = await res.text().catch(() => "");
|
|
284
|
+
throw new Error(`token exchange failed (${res.status}): ${text}`);
|
|
256
285
|
}
|
|
257
|
-
|
|
286
|
+
const payload = await res.json();
|
|
287
|
+
return {
|
|
288
|
+
accessToken: payload.access_token,
|
|
289
|
+
idToken: payload.id_token,
|
|
290
|
+
refreshToken: payload.refresh_token,
|
|
291
|
+
expiresIn: payload.expires_in,
|
|
292
|
+
scope: payload.scope
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
async function verifyIdToken(cfg, idToken) {
|
|
296
|
+
const { set, issuer } = await jwks(cfg);
|
|
297
|
+
return jwtVerify(idToken, set, {
|
|
298
|
+
issuer,
|
|
299
|
+
audience: cfg.clientId
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
function payloadToSession(payload) {
|
|
303
|
+
return {
|
|
304
|
+
sub: String(payload.sub ?? ""),
|
|
305
|
+
name: payload.name,
|
|
306
|
+
email: payload.email,
|
|
307
|
+
emailVerified: payload.email_verified,
|
|
308
|
+
phoneNumber: payload.phone_number,
|
|
309
|
+
phoneNumberVerified: payload.phone_number_verified,
|
|
310
|
+
exp: Number(payload.exp ?? 0),
|
|
311
|
+
iat: Number(payload.iat ?? 0)
|
|
312
|
+
};
|
|
313
|
+
}
|
|
314
|
+
function buildSessionCookie(cfg, idToken, maxAgeSeconds) {
|
|
315
|
+
const name = cookieName(cfg);
|
|
316
|
+
const parts = [
|
|
317
|
+
`${name}=${idToken}`,
|
|
318
|
+
"Path=/",
|
|
319
|
+
"HttpOnly",
|
|
320
|
+
"Secure",
|
|
321
|
+
"SameSite=Lax",
|
|
322
|
+
`Max-Age=${maxAgeSeconds}`
|
|
323
|
+
];
|
|
324
|
+
if (cfg.cookieDomain) parts.push(`Domain=${cfg.cookieDomain}`);
|
|
325
|
+
return parts.join("; ");
|
|
326
|
+
}
|
|
327
|
+
function buildSignoutCookie(cfg) {
|
|
328
|
+
const name = cookieName(cfg);
|
|
329
|
+
const parts = [`${name}=`, "Path=/", "HttpOnly", "Secure", "SameSite=Lax", "Max-Age=0"];
|
|
330
|
+
if (cfg.cookieDomain) parts.push(`Domain=${cfg.cookieDomain}`);
|
|
331
|
+
return parts.join("; ");
|
|
332
|
+
}
|
|
333
|
+
async function handleOidcCallback(req, opts) {
|
|
334
|
+
let body;
|
|
258
335
|
try {
|
|
259
|
-
|
|
336
|
+
body = await req.json();
|
|
260
337
|
} catch {
|
|
261
|
-
return
|
|
338
|
+
return Response.json({ error: "invalid_json" }, { status: 400 });
|
|
262
339
|
}
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
const profile = parseProfile(parsed.profile) ?? options.defaultProfile ?? DEFAULT_PROFILE2;
|
|
266
|
-
const revalidate2 = options.revalidateTag ?? await loadRevalidateTag();
|
|
267
|
-
for (const tag of tags2) revalidate2(tag, profile);
|
|
268
|
-
return Response.json({ ok: true, revalidated: tags2.length, profile });
|
|
269
|
-
}
|
|
270
|
-
function parseProfile(raw) {
|
|
271
|
-
if (typeof raw === "string" && raw.length > 0) return raw;
|
|
272
|
-
if (raw && typeof raw === "object" && "expire" in raw && typeof raw.expire === "number") {
|
|
273
|
-
return { expire: raw.expire };
|
|
340
|
+
if (!body.code || !body.codeVerifier) {
|
|
341
|
+
return Response.json({ error: "missing_code_or_verifier" }, { status: 400 });
|
|
274
342
|
}
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
)
|
|
286
|
-
|
|
287
|
-
return cachedRevalidateTag;
|
|
288
|
-
}
|
|
289
|
-
async function verifyHmac(secret, payload, signatureHeader) {
|
|
290
|
-
if (!signatureHeader.startsWith(SIGNATURE_PREFIX)) return false;
|
|
291
|
-
const providedBytes = hexToBytes(signatureHeader.slice(SIGNATURE_PREFIX.length));
|
|
292
|
-
if (!providedBytes) return false;
|
|
293
|
-
const enc = new TextEncoder();
|
|
294
|
-
const key = await crypto.subtle.importKey(
|
|
295
|
-
"raw",
|
|
296
|
-
enc.encode(secret),
|
|
297
|
-
{ name: "HMAC", hash: "SHA-256" },
|
|
298
|
-
false,
|
|
299
|
-
["verify"]
|
|
300
|
-
);
|
|
301
|
-
return crypto.subtle.verify("HMAC", key, providedBytes, enc.encode(payload));
|
|
302
|
-
}
|
|
303
|
-
function hexToBytes(hex) {
|
|
304
|
-
if (hex.length % 2 !== 0 || !/^[0-9a-f]+$/i.test(hex)) return null;
|
|
305
|
-
const buf = new ArrayBuffer(hex.length / 2);
|
|
306
|
-
const out = new Uint8Array(buf);
|
|
307
|
-
for (let i = 0; i < hex.length; i += 2) {
|
|
308
|
-
out[i / 2] = Number.parseInt(hex.slice(i, i + 2), 16);
|
|
343
|
+
let tokens;
|
|
344
|
+
try {
|
|
345
|
+
tokens = await exchangeCode({
|
|
346
|
+
...opts,
|
|
347
|
+
code: body.code,
|
|
348
|
+
codeVerifier: body.codeVerifier
|
|
349
|
+
});
|
|
350
|
+
} catch (e) {
|
|
351
|
+
return Response.json({ error: "exchange_failed", detail: String(e) }, { status: 400 });
|
|
352
|
+
}
|
|
353
|
+
if (!tokens.idToken) {
|
|
354
|
+
return Response.json({ error: "missing_id_token" }, { status: 400 });
|
|
309
355
|
}
|
|
310
|
-
|
|
356
|
+
try {
|
|
357
|
+
await verifyIdToken(opts, tokens.idToken);
|
|
358
|
+
} catch (e) {
|
|
359
|
+
return Response.json({ error: "id_token_invalid", detail: String(e) }, { status: 401 });
|
|
360
|
+
}
|
|
361
|
+
const cookie = buildSessionCookie(opts, tokens.idToken, tokens.expiresIn);
|
|
362
|
+
return new Response(JSON.stringify({ ok: true }), {
|
|
363
|
+
status: 200,
|
|
364
|
+
headers: { "Content-Type": "application/json", "Set-Cookie": cookie }
|
|
365
|
+
});
|
|
311
366
|
}
|
|
312
|
-
function
|
|
313
|
-
const
|
|
314
|
-
|
|
367
|
+
async function handleSessionRequest(req, cfg) {
|
|
368
|
+
const session = await getSessionFromCookieHeader(cfg, req.headers.get("cookie"));
|
|
369
|
+
if (!session) {
|
|
370
|
+
return new Response(JSON.stringify({ sub: null }), {
|
|
371
|
+
status: 200,
|
|
372
|
+
headers: { "Content-Type": "application/json", "Cache-Control": "no-store" }
|
|
373
|
+
});
|
|
374
|
+
}
|
|
375
|
+
return new Response(JSON.stringify(session), {
|
|
376
|
+
status: 200,
|
|
377
|
+
headers: { "Content-Type": "application/json", "Cache-Control": "no-store" }
|
|
378
|
+
});
|
|
315
379
|
}
|
|
316
|
-
function
|
|
317
|
-
|
|
380
|
+
async function getSessionFromCookieHeader(cfg, cookieHeader) {
|
|
381
|
+
if (!cookieHeader) return null;
|
|
382
|
+
const name = cookieName(cfg);
|
|
383
|
+
const match = cookieHeader.split(/;\s*/).find((p) => p.startsWith(`${name}=`));
|
|
384
|
+
if (!match) return null;
|
|
385
|
+
const token = match.slice(name.length + 1);
|
|
386
|
+
if (!token) return null;
|
|
387
|
+
try {
|
|
388
|
+
const { payload } = await verifyIdToken(cfg, token);
|
|
389
|
+
return payloadToSession(payload);
|
|
390
|
+
} catch {
|
|
391
|
+
return null;
|
|
392
|
+
}
|
|
318
393
|
}
|
|
319
394
|
|
|
320
|
-
export { CACHE_LIFE_DEFAULT, CACHE_LIFE_PROBE, getServerClient, refreshPage, revalidateAddOn, revalidateAddOns, revalidateBrand, revalidateBusiness, revalidateByTag, revalidateCategories, revalidateCategory, revalidateCollection, revalidateCollections, revalidateLocation, revalidateLocations, revalidatePricing, revalidateProduct, revalidateProducts,
|
|
395
|
+
export { CACHE_LIFE_DEFAULT, CACHE_LIFE_PROBE, buildSessionCookie, buildSignoutCookie, exchangeCode, getServerClient, getSessionFromCookieHeader, handleOidcCallback, handleSessionRequest, refreshPage, revalidateAddOn, revalidateAddOns, revalidateBrand, revalidateBusiness, revalidateByTag, revalidateCategories, revalidateCategory, revalidateCollection, revalidateCollections, revalidateLocation, revalidateLocations, revalidatePricing, revalidateProduct, revalidateProducts, revalidateStock, revalidateSubscription, revalidateSubscriptions, tags, updateAddOn, updateAddOns, updateBrand, updateBusiness, updateByTag, updateCategories, updateCategory, updateCollection, updateCollections, updateLocation, updateLocations, updatePricing, updateProduct, updateProducts, updateStock, updateSubscription, updateSubscriptions, verifyIdToken };
|