@sylphx/sdk 0.3.2 → 0.3.4

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.
@@ -2,7 +2,7 @@
2
2
  import { NextResponse } from "next/server";
3
3
 
4
4
  // src/constants.ts
5
- var DEFAULT_PLATFORM_URL = "https://sylphx.com";
5
+ var DEFAULT_SDK_API_HOST = "api.sylphx.com";
6
6
  var SDK_PLATFORM = typeof window !== "undefined" ? "browser" : typeof process !== "undefined" && process.versions?.node ? "node" : "unknown";
7
7
  var TOKEN_EXPIRY_BUFFER_MS = 3e4;
8
8
  var SESSION_TOKEN_LIFETIME_SECONDS = 5 * 60;
@@ -347,7 +347,7 @@ async function handleCallback(request, ctx) {
347
347
  return NextResponse.redirect(url);
348
348
  }
349
349
  try {
350
- const res = await fetch(`${ctx.platformUrl}/api/v1/auth/token`, {
350
+ const res = await fetch(`${ctx.platformUrl}/v1/auth/token`, {
351
351
  method: "POST",
352
352
  headers: { "Content-Type": "application/json" },
353
353
  body: JSON.stringify({
@@ -385,7 +385,7 @@ async function handleSignOut(request, ctx) {
385
385
  const refreshToken = request.cookies.get(ctx.cookieNames.REFRESH)?.value;
386
386
  if (refreshToken) {
387
387
  try {
388
- await fetch(`${ctx.platformUrl}/api/v1/auth/revoke`, {
388
+ await fetch(`${ctx.platformUrl}/v1/auth/revoke`, {
389
389
  method: "POST",
390
390
  headers: { "Content-Type": "application/json" },
391
391
  body: JSON.stringify({
@@ -419,7 +419,7 @@ function handleToken(request, ctx) {
419
419
  async function refreshTokens(refreshToken, ctx) {
420
420
  ctx.log("Refreshing tokens");
421
421
  try {
422
- const res = await fetch(`${ctx.platformUrl}/api/v1/auth/token`, {
422
+ const res = await fetch(`${ctx.platformUrl}/v1/auth/token`, {
423
423
  method: "POST",
424
424
  headers: { "Content-Type": "application/json" },
425
425
  body: JSON.stringify({
@@ -452,7 +452,7 @@ function createSylphxMiddleware(userConfig = {}) {
452
452
  );
453
453
  }
454
454
  const secretKey = validateAndSanitizeSecretKey(rawSecretKey);
455
- const platformUrl = (userConfig.platformUrl || process.env.SYLPHX_PLATFORM_URL || DEFAULT_PLATFORM_URL).trim();
455
+ const platformUrl = (userConfig.platformUrl || `https://${DEFAULT_SDK_API_HOST}`).trim();
456
456
  const namespace = getCookieNamespace(secretKey);
457
457
  const cookieNames = getCookieNames(namespace);
458
458
  const config = {
@@ -548,7 +548,7 @@ function getNamespace(secretKey) {
548
548
  // src/nextjs/server.ts
549
549
  import { cache as cache2 } from "react";
550
550
 
551
- // ../../node_modules/jose/dist/webapi/lib/buffer_utils.js
551
+ // node_modules/jose/dist/webapi/lib/buffer_utils.js
552
552
  var encoder = new TextEncoder();
553
553
  var decoder = new TextDecoder();
554
554
  var MAX_INT32 = 2 ** 32;
@@ -574,7 +574,7 @@ function encode(string) {
574
574
  return bytes;
575
575
  }
576
576
 
577
- // ../../node_modules/jose/dist/webapi/lib/base64.js
577
+ // node_modules/jose/dist/webapi/lib/base64.js
578
578
  function decodeBase64(encoded) {
579
579
  if (Uint8Array.fromBase64) {
580
580
  return Uint8Array.fromBase64(encoded);
@@ -587,7 +587,7 @@ function decodeBase64(encoded) {
587
587
  return bytes;
588
588
  }
589
589
 
590
- // ../../node_modules/jose/dist/webapi/util/base64url.js
590
+ // node_modules/jose/dist/webapi/util/base64url.js
591
591
  function decode(input) {
592
592
  if (Uint8Array.fromBase64) {
593
593
  return Uint8Array.fromBase64(typeof input === "string" ? input : decoder.decode(input), {
@@ -606,7 +606,7 @@ function decode(input) {
606
606
  }
607
607
  }
608
608
 
609
- // ../../node_modules/jose/dist/webapi/util/errors.js
609
+ // node_modules/jose/dist/webapi/util/errors.js
610
610
  var JOSEError = class extends Error {
611
611
  static code = "ERR_JOSE_GENERIC";
612
612
  code = "ERR_JOSE_GENERIC";
@@ -666,7 +666,7 @@ var JWSSignatureVerificationFailed = class extends JOSEError {
666
666
  }
667
667
  };
668
668
 
669
- // ../../node_modules/jose/dist/webapi/lib/crypto_key.js
669
+ // node_modules/jose/dist/webapi/lib/crypto_key.js
670
670
  var unusable = (name, prop = "algorithm.name") => new TypeError(`CryptoKey does not support this operation, its ${prop} must be ${name}`);
671
671
  var isAlgorithm = (algorithm, name) => algorithm.name === name;
672
672
  function getHashLength(hash) {
@@ -754,7 +754,7 @@ function checkSigCryptoKey(key, alg, usage) {
754
754
  checkUsage(key, usage);
755
755
  }
756
756
 
757
- // ../../node_modules/jose/dist/webapi/lib/invalid_key_input.js
757
+ // node_modules/jose/dist/webapi/lib/invalid_key_input.js
758
758
  function message(msg, actual, ...types) {
759
759
  types = types.filter(Boolean);
760
760
  if (types.length > 2) {
@@ -779,7 +779,7 @@ function message(msg, actual, ...types) {
779
779
  var invalidKeyInput = (actual, ...types) => message("Key must be ", actual, ...types);
780
780
  var withAlg = (alg, actual, ...types) => message(`Key for the ${alg} algorithm must be `, actual, ...types);
781
781
 
782
- // ../../node_modules/jose/dist/webapi/lib/is_key_like.js
782
+ // node_modules/jose/dist/webapi/lib/is_key_like.js
783
783
  var isCryptoKey = (key) => {
784
784
  if (key?.[Symbol.toStringTag] === "CryptoKey")
785
785
  return true;
@@ -792,7 +792,7 @@ var isCryptoKey = (key) => {
792
792
  var isKeyObject = (key) => key?.[Symbol.toStringTag] === "KeyObject";
793
793
  var isKeyLike = (key) => isCryptoKey(key) || isKeyObject(key);
794
794
 
795
- // ../../node_modules/jose/dist/webapi/lib/is_disjoint.js
795
+ // node_modules/jose/dist/webapi/lib/is_disjoint.js
796
796
  function isDisjoint(...headers) {
797
797
  const sources = headers.filter(Boolean);
798
798
  if (sources.length === 0 || sources.length === 1) {
@@ -815,7 +815,7 @@ function isDisjoint(...headers) {
815
815
  return true;
816
816
  }
817
817
 
818
- // ../../node_modules/jose/dist/webapi/lib/is_object.js
818
+ // node_modules/jose/dist/webapi/lib/is_object.js
819
819
  var isObjectLike = (value) => typeof value === "object" && value !== null;
820
820
  function isObject(input) {
821
821
  if (!isObjectLike(input) || Object.prototype.toString.call(input) !== "[object Object]") {
@@ -831,7 +831,7 @@ function isObject(input) {
831
831
  return Object.getPrototypeOf(input) === proto;
832
832
  }
833
833
 
834
- // ../../node_modules/jose/dist/webapi/lib/check_key_length.js
834
+ // node_modules/jose/dist/webapi/lib/check_key_length.js
835
835
  function checkKeyLength(alg, key) {
836
836
  if (alg.startsWith("RS") || alg.startsWith("PS")) {
837
837
  const { modulusLength } = key.algorithm;
@@ -841,7 +841,7 @@ function checkKeyLength(alg, key) {
841
841
  }
842
842
  }
843
843
 
844
- // ../../node_modules/jose/dist/webapi/lib/jwk_to_key.js
844
+ // node_modules/jose/dist/webapi/lib/jwk_to_key.js
845
845
  function subtleMapping(jwk) {
846
846
  let algorithm;
847
847
  let keyUsages;
@@ -951,7 +951,7 @@ async function jwkToKey(jwk) {
951
951
  return crypto.subtle.importKey("jwk", keyData, algorithm, jwk.ext ?? (jwk.d || jwk.priv ? false : true), jwk.key_ops ?? keyUsages);
952
952
  }
953
953
 
954
- // ../../node_modules/jose/dist/webapi/key/import.js
954
+ // node_modules/jose/dist/webapi/key/import.js
955
955
  async function importJWK(jwk, alg, options) {
956
956
  if (!isObject(jwk)) {
957
957
  throw new TypeError("JWK must be an object");
@@ -987,7 +987,7 @@ async function importJWK(jwk, alg, options) {
987
987
  }
988
988
  }
989
989
 
990
- // ../../node_modules/jose/dist/webapi/lib/validate_crit.js
990
+ // node_modules/jose/dist/webapi/lib/validate_crit.js
991
991
  function validateCrit(Err, recognizedDefault, recognizedOption, protectedHeader, joseHeader) {
992
992
  if (joseHeader.crit !== void 0 && protectedHeader?.crit === void 0) {
993
993
  throw new Err('"crit" (Critical) Header Parameter MUST be integrity protected');
@@ -1018,7 +1018,7 @@ function validateCrit(Err, recognizedDefault, recognizedOption, protectedHeader,
1018
1018
  return new Set(protectedHeader.crit);
1019
1019
  }
1020
1020
 
1021
- // ../../node_modules/jose/dist/webapi/lib/validate_algorithms.js
1021
+ // node_modules/jose/dist/webapi/lib/validate_algorithms.js
1022
1022
  function validateAlgorithms(option, algorithms) {
1023
1023
  if (algorithms !== void 0 && (!Array.isArray(algorithms) || algorithms.some((s) => typeof s !== "string"))) {
1024
1024
  throw new TypeError(`"${option}" option must be an array of strings`);
@@ -1029,13 +1029,13 @@ function validateAlgorithms(option, algorithms) {
1029
1029
  return new Set(algorithms);
1030
1030
  }
1031
1031
 
1032
- // ../../node_modules/jose/dist/webapi/lib/is_jwk.js
1032
+ // node_modules/jose/dist/webapi/lib/is_jwk.js
1033
1033
  var isJWK = (key) => isObject(key) && typeof key.kty === "string";
1034
1034
  var isPrivateJWK = (key) => key.kty !== "oct" && (key.kty === "AKP" && typeof key.priv === "string" || typeof key.d === "string");
1035
1035
  var isPublicJWK = (key) => key.kty !== "oct" && key.d === void 0 && key.priv === void 0;
1036
1036
  var isSecretJWK = (key) => key.kty === "oct" && typeof key.k === "string";
1037
1037
 
1038
- // ../../node_modules/jose/dist/webapi/lib/normalize_key.js
1038
+ // node_modules/jose/dist/webapi/lib/normalize_key.js
1039
1039
  var cache;
1040
1040
  var handleJWK = async (key, jwk, alg, freeze = false) => {
1041
1041
  cache ||= /* @__PURE__ */ new WeakMap();
@@ -1206,7 +1206,7 @@ async function normalizeKey(key, alg) {
1206
1206
  throw new Error("unreachable");
1207
1207
  }
1208
1208
 
1209
- // ../../node_modules/jose/dist/webapi/lib/check_key_type.js
1209
+ // node_modules/jose/dist/webapi/lib/check_key_type.js
1210
1210
  var tag = (key) => key?.[Symbol.toStringTag];
1211
1211
  var jwkMatchesOp = (alg, key, usage) => {
1212
1212
  if (key.use !== void 0) {
@@ -1326,7 +1326,7 @@ function checkKeyType(alg, key, usage) {
1326
1326
  }
1327
1327
  }
1328
1328
 
1329
- // ../../node_modules/jose/dist/webapi/lib/subtle_dsa.js
1329
+ // node_modules/jose/dist/webapi/lib/subtle_dsa.js
1330
1330
  function subtleAlgorithm(alg, algorithm) {
1331
1331
  const hash = `SHA-${alg.slice(-3)}`;
1332
1332
  switch (alg) {
@@ -1358,7 +1358,7 @@ function subtleAlgorithm(alg, algorithm) {
1358
1358
  }
1359
1359
  }
1360
1360
 
1361
- // ../../node_modules/jose/dist/webapi/lib/get_sign_verify_key.js
1361
+ // node_modules/jose/dist/webapi/lib/get_sign_verify_key.js
1362
1362
  async function getSigKey(alg, key, usage) {
1363
1363
  if (key instanceof Uint8Array) {
1364
1364
  if (!alg.startsWith("HS")) {
@@ -1370,7 +1370,7 @@ async function getSigKey(alg, key, usage) {
1370
1370
  return key;
1371
1371
  }
1372
1372
 
1373
- // ../../node_modules/jose/dist/webapi/lib/verify.js
1373
+ // node_modules/jose/dist/webapi/lib/verify.js
1374
1374
  async function verify(alg, key, signature, data) {
1375
1375
  const cryptoKey = await getSigKey(alg, key, "verify");
1376
1376
  checkKeyLength(alg, cryptoKey);
@@ -1382,7 +1382,7 @@ async function verify(alg, key, signature, data) {
1382
1382
  }
1383
1383
  }
1384
1384
 
1385
- // ../../node_modules/jose/dist/webapi/jws/flattened/verify.js
1385
+ // node_modules/jose/dist/webapi/jws/flattened/verify.js
1386
1386
  async function flattenedVerify(jws, key, options) {
1387
1387
  if (!isObject(jws)) {
1388
1388
  throw new JWSInvalid("Flattened JWS must be an object");
@@ -1484,7 +1484,7 @@ async function flattenedVerify(jws, key, options) {
1484
1484
  return result;
1485
1485
  }
1486
1486
 
1487
- // ../../node_modules/jose/dist/webapi/jws/compact/verify.js
1487
+ // node_modules/jose/dist/webapi/jws/compact/verify.js
1488
1488
  async function compactVerify(jws, key, options) {
1489
1489
  if (jws instanceof Uint8Array) {
1490
1490
  jws = decoder.decode(jws);
@@ -1504,7 +1504,7 @@ async function compactVerify(jws, key, options) {
1504
1504
  return result;
1505
1505
  }
1506
1506
 
1507
- // ../../node_modules/jose/dist/webapi/lib/jwt_claims_set.js
1507
+ // node_modules/jose/dist/webapi/lib/jwt_claims_set.js
1508
1508
  var epoch = (date) => Math.floor(date.getTime() / 1e3);
1509
1509
  var minute = 60;
1510
1510
  var hour = minute * 60;
@@ -1661,7 +1661,7 @@ function validateClaimsSet(protectedHeader, encodedPayload, options = {}) {
1661
1661
  return payload;
1662
1662
  }
1663
1663
 
1664
- // ../../node_modules/jose/dist/webapi/jwt/verify.js
1664
+ // node_modules/jose/dist/webapi/jwt/verify.js
1665
1665
  async function jwtVerify(jwt, key, options) {
1666
1666
  const verified = await compactVerify(jwt, key, options);
1667
1667
  if (verified.protectedHeader.crit?.includes("b64") && verified.protectedHeader.b64 === false) {
@@ -1675,6 +1675,69 @@ async function jwtVerify(jwt, key, options) {
1675
1675
  return result;
1676
1676
  }
1677
1677
 
1678
+ // src/lib/ids.ts
1679
+ var CB32 = "0123456789abcdefghjkmnpqrstvwxyz";
1680
+ var CB32_MAP = Object.fromEntries([...CB32].map((c, i) => [c, i]));
1681
+ var B58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
1682
+ var B58_MAP = Object.fromEntries([...B58].map((c, i) => [c, i]));
1683
+ function cb32Encode(hex) {
1684
+ const num = BigInt(`0x${hex}`);
1685
+ const chars = [];
1686
+ let n = num;
1687
+ for (let i = 0; i < 26; i++) {
1688
+ chars.unshift(CB32[Number(n & 0x1fn)]);
1689
+ n >>= 5n;
1690
+ }
1691
+ return chars.join("");
1692
+ }
1693
+ function cb32Decode(str) {
1694
+ if (str.length !== 26) return null;
1695
+ let n = 0n;
1696
+ for (const c of str.toLowerCase()) {
1697
+ const idx = CB32_MAP[c];
1698
+ if (idx === void 0) return null;
1699
+ n = n << 5n | BigInt(idx);
1700
+ }
1701
+ return n.toString(16).padStart(32, "0");
1702
+ }
1703
+ function b58Decode(str) {
1704
+ let n = 0n;
1705
+ for (const c of str) {
1706
+ const i = B58_MAP[c] ?? -1;
1707
+ if (i === -1) return null;
1708
+ n = n * 58n + BigInt(i);
1709
+ }
1710
+ const hex = n.toString(16).padStart(32, "0");
1711
+ return hex.length === 32 ? hex : null;
1712
+ }
1713
+ function hexToUuid(hex) {
1714
+ return [
1715
+ hex.slice(0, 8),
1716
+ hex.slice(8, 12),
1717
+ hex.slice(12, 16),
1718
+ hex.slice(16, 20),
1719
+ hex.slice(20)
1720
+ ].join("-");
1721
+ }
1722
+ function encodeUserId(uuid) {
1723
+ const hex = uuid.replace(/-/g, "");
1724
+ if (hex.length !== 32)
1725
+ throw new Error("Invalid UUID: expected 32 hex chars after stripping dashes");
1726
+ return `user_${cb32Encode(hex)}`;
1727
+ }
1728
+ function decodeUserId(prefixedId) {
1729
+ if (!prefixedId.startsWith("user_")) return null;
1730
+ const enc = prefixedId.slice(5);
1731
+ if (!enc) return null;
1732
+ if (enc.length === 26) {
1733
+ const hex2 = cb32Decode(enc);
1734
+ if (hex2) return hexToUuid(hex2);
1735
+ }
1736
+ const hex = b58Decode(enc);
1737
+ if (hex) return hexToUuid(hex);
1738
+ return null;
1739
+ }
1740
+
1678
1741
  // src/server/index.ts
1679
1742
  function isJwksResponse(data) {
1680
1743
  return typeof data === "object" && data !== null && "keys" in data && Array.isArray(data.keys);
@@ -1683,7 +1746,7 @@ function isAccessTokenPayload(payload) {
1683
1746
  return typeof payload.sub === "string" && typeof payload.email === "string" && typeof payload.app_id === "string" && typeof payload.iat === "number" && typeof payload.exp === "number";
1684
1747
  }
1685
1748
  var jwksCache = null;
1686
- async function getJwks(platformUrl = DEFAULT_PLATFORM_URL) {
1749
+ async function getJwks(platformUrl = `https://${DEFAULT_SDK_API_HOST}`) {
1687
1750
  const now = Date.now();
1688
1751
  if (jwksCache && jwksCache.expiresAt > now) {
1689
1752
  return jwksCache.keys;
@@ -1704,7 +1767,7 @@ async function getJwks(platformUrl = DEFAULT_PLATFORM_URL) {
1704
1767
  return data.keys;
1705
1768
  }
1706
1769
  async function verifyAccessToken(token, options) {
1707
- const platformUrl = options.platformUrl || DEFAULT_PLATFORM_URL;
1770
+ const platformUrl = options.platformUrl || `https://${DEFAULT_SDK_API_HOST}`;
1708
1771
  const keys = await getJwks(platformUrl);
1709
1772
  if (!keys.length) {
1710
1773
  throw new Error("No keys in JWKS");
@@ -1721,6 +1784,7 @@ async function verifyAccessToken(token, options) {
1721
1784
  }
1722
1785
  return {
1723
1786
  sub: payload.sub,
1787
+ pid: payload.pid,
1724
1788
  email: payload.email,
1725
1789
  name: payload.name,
1726
1790
  picture: payload.picture,
@@ -1746,7 +1810,7 @@ function configureServer(config) {
1746
1810
  const secretKey = validateAndSanitizeSecretKey(config.secretKey);
1747
1811
  serverConfig = {
1748
1812
  secretKey,
1749
- platformUrl: (config.platformUrl || DEFAULT_PLATFORM_URL).trim()
1813
+ platformUrl: `https://${DEFAULT_SDK_API_HOST}`.trim()
1750
1814
  };
1751
1815
  }
1752
1816
  function getConfig() {
@@ -1759,7 +1823,7 @@ function getConfig() {
1759
1823
  }
1760
1824
  try {
1761
1825
  const secretKey = validateAndSanitizeSecretKey(rawSecretKey);
1762
- const platformUrl = (process.env.SYLPHX_PLATFORM_URL || DEFAULT_PLATFORM_URL).trim();
1826
+ const platformUrl = `https://${DEFAULT_SDK_API_HOST}`.trim();
1763
1827
  serverConfig = { secretKey, platformUrl };
1764
1828
  return serverConfig;
1765
1829
  } catch (error) {
@@ -1785,10 +1849,11 @@ var auth = cache2(async () => {
1785
1849
  if (sessionToken && expiresAt && expiresAt > Date.now() + TOKEN_EXPIRY_BUFFER_MS) {
1786
1850
  try {
1787
1851
  const payload = await verifyAccessToken(sessionToken, config);
1852
+ const resolvedUserId = payload.pid ?? payload.sub;
1788
1853
  return {
1789
- userId: payload.sub,
1854
+ userId: resolvedUserId,
1790
1855
  user: user || {
1791
- id: payload.sub,
1856
+ id: resolvedUserId,
1792
1857
  email: payload.email,
1793
1858
  name: payload.name || null,
1794
1859
  image: payload.picture || null,
@@ -1824,7 +1889,7 @@ async function handleCallback2(code) {
1824
1889
  if (!config) {
1825
1890
  throw new Error("Sylphx SDK not configured. Set SYLPHX_SECRET_KEY environment variable.");
1826
1891
  }
1827
- const response = await fetch(`${config.platformUrl}/api/v1/auth/token`, {
1892
+ const response = await fetch(`${config.platformUrl}/v1/auth/token`, {
1828
1893
  method: "POST",
1829
1894
  headers: { "Content-Type": "application/json" },
1830
1895
  body: JSON.stringify({
@@ -1854,7 +1919,7 @@ async function signOut() {
1854
1919
  const { refreshToken } = await getAuthCookies(namespace);
1855
1920
  if (refreshToken) {
1856
1921
  try {
1857
- await fetch(`${config.platformUrl}/api/v1/auth/revoke`, {
1922
+ await fetch(`${config.platformUrl}/v1/auth/revoke`, {
1858
1923
  method: "POST",
1859
1924
  headers: { "Content-Type": "application/json" },
1860
1925
  body: JSON.stringify({
@@ -1914,6 +1979,8 @@ export {
1914
1979
  createSylphxMiddleware,
1915
1980
  currentUser,
1916
1981
  currentUserId,
1982
+ decodeUserId,
1983
+ encodeUserId,
1917
1984
  getAuthCookies,
1918
1985
  getAuthorizationUrl,
1919
1986
  getCookieNames,