@sylphx/sdk 0.3.1 → 0.3.3

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.
@@ -34,6 +34,8 @@ __export(nextjs_exports, {
34
34
  createSylphxMiddleware: () => createSylphxMiddleware,
35
35
  currentUser: () => currentUser,
36
36
  currentUserId: () => currentUserId,
37
+ decodeUserId: () => decodeUserId,
38
+ encodeUserId: () => encodeUserId,
37
39
  getAuthCookies: () => getAuthCookies,
38
40
  getAuthorizationUrl: () => getAuthorizationUrl,
39
41
  getCookieNames: () => getCookieNames,
@@ -54,7 +56,7 @@ module.exports = __toCommonJS(nextjs_exports);
54
56
  var import_server = require("next/server");
55
57
 
56
58
  // src/constants.ts
57
- var DEFAULT_PLATFORM_URL = "https://sylphx.com";
59
+ var DEFAULT_SDK_API_HOST = "api.sylphx.com";
58
60
  var SDK_PLATFORM = typeof window !== "undefined" ? "browser" : typeof process !== "undefined" && process.versions?.node ? "node" : "unknown";
59
61
  var TOKEN_EXPIRY_BUFFER_MS = 3e4;
60
62
  var SESSION_TOKEN_LIFETIME_SECONDS = 5 * 60;
@@ -399,7 +401,7 @@ async function handleCallback(request, ctx) {
399
401
  return import_server.NextResponse.redirect(url);
400
402
  }
401
403
  try {
402
- const res = await fetch(`${ctx.platformUrl}/api/v1/auth/token`, {
404
+ const res = await fetch(`${ctx.platformUrl}/v1/auth/token`, {
403
405
  method: "POST",
404
406
  headers: { "Content-Type": "application/json" },
405
407
  body: JSON.stringify({
@@ -437,7 +439,7 @@ async function handleSignOut(request, ctx) {
437
439
  const refreshToken = request.cookies.get(ctx.cookieNames.REFRESH)?.value;
438
440
  if (refreshToken) {
439
441
  try {
440
- await fetch(`${ctx.platformUrl}/api/v1/auth/revoke`, {
442
+ await fetch(`${ctx.platformUrl}/v1/auth/revoke`, {
441
443
  method: "POST",
442
444
  headers: { "Content-Type": "application/json" },
443
445
  body: JSON.stringify({
@@ -471,7 +473,7 @@ function handleToken(request, ctx) {
471
473
  async function refreshTokens(refreshToken, ctx) {
472
474
  ctx.log("Refreshing tokens");
473
475
  try {
474
- const res = await fetch(`${ctx.platformUrl}/api/v1/auth/token`, {
476
+ const res = await fetch(`${ctx.platformUrl}/v1/auth/token`, {
475
477
  method: "POST",
476
478
  headers: { "Content-Type": "application/json" },
477
479
  body: JSON.stringify({
@@ -504,7 +506,7 @@ function createSylphxMiddleware(userConfig = {}) {
504
506
  );
505
507
  }
506
508
  const secretKey = validateAndSanitizeSecretKey(rawSecretKey);
507
- const platformUrl = (userConfig.platformUrl || process.env.SYLPHX_PLATFORM_URL || DEFAULT_PLATFORM_URL).trim();
509
+ const platformUrl = (userConfig.platformUrl || `https://${DEFAULT_SDK_API_HOST}`).trim();
508
510
  const namespace = getCookieNamespace(secretKey);
509
511
  const cookieNames = getCookieNames(namespace);
510
512
  const config = {
@@ -600,7 +602,7 @@ function getNamespace(secretKey) {
600
602
  // src/nextjs/server.ts
601
603
  var import_react = require("react");
602
604
 
603
- // ../../node_modules/jose/dist/webapi/lib/buffer_utils.js
605
+ // node_modules/jose/dist/webapi/lib/buffer_utils.js
604
606
  var encoder = new TextEncoder();
605
607
  var decoder = new TextDecoder();
606
608
  var MAX_INT32 = 2 ** 32;
@@ -626,7 +628,7 @@ function encode(string) {
626
628
  return bytes;
627
629
  }
628
630
 
629
- // ../../node_modules/jose/dist/webapi/lib/base64.js
631
+ // node_modules/jose/dist/webapi/lib/base64.js
630
632
  function decodeBase64(encoded) {
631
633
  if (Uint8Array.fromBase64) {
632
634
  return Uint8Array.fromBase64(encoded);
@@ -639,7 +641,7 @@ function decodeBase64(encoded) {
639
641
  return bytes;
640
642
  }
641
643
 
642
- // ../../node_modules/jose/dist/webapi/util/base64url.js
644
+ // node_modules/jose/dist/webapi/util/base64url.js
643
645
  function decode(input) {
644
646
  if (Uint8Array.fromBase64) {
645
647
  return Uint8Array.fromBase64(typeof input === "string" ? input : decoder.decode(input), {
@@ -658,7 +660,7 @@ function decode(input) {
658
660
  }
659
661
  }
660
662
 
661
- // ../../node_modules/jose/dist/webapi/util/errors.js
663
+ // node_modules/jose/dist/webapi/util/errors.js
662
664
  var JOSEError = class extends Error {
663
665
  static code = "ERR_JOSE_GENERIC";
664
666
  code = "ERR_JOSE_GENERIC";
@@ -718,7 +720,7 @@ var JWSSignatureVerificationFailed = class extends JOSEError {
718
720
  }
719
721
  };
720
722
 
721
- // ../../node_modules/jose/dist/webapi/lib/crypto_key.js
723
+ // node_modules/jose/dist/webapi/lib/crypto_key.js
722
724
  var unusable = (name, prop = "algorithm.name") => new TypeError(`CryptoKey does not support this operation, its ${prop} must be ${name}`);
723
725
  var isAlgorithm = (algorithm, name) => algorithm.name === name;
724
726
  function getHashLength(hash) {
@@ -806,7 +808,7 @@ function checkSigCryptoKey(key, alg, usage) {
806
808
  checkUsage(key, usage);
807
809
  }
808
810
 
809
- // ../../node_modules/jose/dist/webapi/lib/invalid_key_input.js
811
+ // node_modules/jose/dist/webapi/lib/invalid_key_input.js
810
812
  function message(msg, actual, ...types) {
811
813
  types = types.filter(Boolean);
812
814
  if (types.length > 2) {
@@ -831,7 +833,7 @@ function message(msg, actual, ...types) {
831
833
  var invalidKeyInput = (actual, ...types) => message("Key must be ", actual, ...types);
832
834
  var withAlg = (alg, actual, ...types) => message(`Key for the ${alg} algorithm must be `, actual, ...types);
833
835
 
834
- // ../../node_modules/jose/dist/webapi/lib/is_key_like.js
836
+ // node_modules/jose/dist/webapi/lib/is_key_like.js
835
837
  var isCryptoKey = (key) => {
836
838
  if (key?.[Symbol.toStringTag] === "CryptoKey")
837
839
  return true;
@@ -844,7 +846,7 @@ var isCryptoKey = (key) => {
844
846
  var isKeyObject = (key) => key?.[Symbol.toStringTag] === "KeyObject";
845
847
  var isKeyLike = (key) => isCryptoKey(key) || isKeyObject(key);
846
848
 
847
- // ../../node_modules/jose/dist/webapi/lib/is_disjoint.js
849
+ // node_modules/jose/dist/webapi/lib/is_disjoint.js
848
850
  function isDisjoint(...headers) {
849
851
  const sources = headers.filter(Boolean);
850
852
  if (sources.length === 0 || sources.length === 1) {
@@ -867,7 +869,7 @@ function isDisjoint(...headers) {
867
869
  return true;
868
870
  }
869
871
 
870
- // ../../node_modules/jose/dist/webapi/lib/is_object.js
872
+ // node_modules/jose/dist/webapi/lib/is_object.js
871
873
  var isObjectLike = (value) => typeof value === "object" && value !== null;
872
874
  function isObject(input) {
873
875
  if (!isObjectLike(input) || Object.prototype.toString.call(input) !== "[object Object]") {
@@ -883,7 +885,7 @@ function isObject(input) {
883
885
  return Object.getPrototypeOf(input) === proto;
884
886
  }
885
887
 
886
- // ../../node_modules/jose/dist/webapi/lib/check_key_length.js
888
+ // node_modules/jose/dist/webapi/lib/check_key_length.js
887
889
  function checkKeyLength(alg, key) {
888
890
  if (alg.startsWith("RS") || alg.startsWith("PS")) {
889
891
  const { modulusLength } = key.algorithm;
@@ -893,7 +895,7 @@ function checkKeyLength(alg, key) {
893
895
  }
894
896
  }
895
897
 
896
- // ../../node_modules/jose/dist/webapi/lib/jwk_to_key.js
898
+ // node_modules/jose/dist/webapi/lib/jwk_to_key.js
897
899
  function subtleMapping(jwk) {
898
900
  let algorithm;
899
901
  let keyUsages;
@@ -1003,7 +1005,7 @@ async function jwkToKey(jwk) {
1003
1005
  return crypto.subtle.importKey("jwk", keyData, algorithm, jwk.ext ?? (jwk.d || jwk.priv ? false : true), jwk.key_ops ?? keyUsages);
1004
1006
  }
1005
1007
 
1006
- // ../../node_modules/jose/dist/webapi/key/import.js
1008
+ // node_modules/jose/dist/webapi/key/import.js
1007
1009
  async function importJWK(jwk, alg, options) {
1008
1010
  if (!isObject(jwk)) {
1009
1011
  throw new TypeError("JWK must be an object");
@@ -1039,7 +1041,7 @@ async function importJWK(jwk, alg, options) {
1039
1041
  }
1040
1042
  }
1041
1043
 
1042
- // ../../node_modules/jose/dist/webapi/lib/validate_crit.js
1044
+ // node_modules/jose/dist/webapi/lib/validate_crit.js
1043
1045
  function validateCrit(Err, recognizedDefault, recognizedOption, protectedHeader, joseHeader) {
1044
1046
  if (joseHeader.crit !== void 0 && protectedHeader?.crit === void 0) {
1045
1047
  throw new Err('"crit" (Critical) Header Parameter MUST be integrity protected');
@@ -1070,7 +1072,7 @@ function validateCrit(Err, recognizedDefault, recognizedOption, protectedHeader,
1070
1072
  return new Set(protectedHeader.crit);
1071
1073
  }
1072
1074
 
1073
- // ../../node_modules/jose/dist/webapi/lib/validate_algorithms.js
1075
+ // node_modules/jose/dist/webapi/lib/validate_algorithms.js
1074
1076
  function validateAlgorithms(option, algorithms) {
1075
1077
  if (algorithms !== void 0 && (!Array.isArray(algorithms) || algorithms.some((s) => typeof s !== "string"))) {
1076
1078
  throw new TypeError(`"${option}" option must be an array of strings`);
@@ -1081,13 +1083,13 @@ function validateAlgorithms(option, algorithms) {
1081
1083
  return new Set(algorithms);
1082
1084
  }
1083
1085
 
1084
- // ../../node_modules/jose/dist/webapi/lib/is_jwk.js
1086
+ // node_modules/jose/dist/webapi/lib/is_jwk.js
1085
1087
  var isJWK = (key) => isObject(key) && typeof key.kty === "string";
1086
1088
  var isPrivateJWK = (key) => key.kty !== "oct" && (key.kty === "AKP" && typeof key.priv === "string" || typeof key.d === "string");
1087
1089
  var isPublicJWK = (key) => key.kty !== "oct" && key.d === void 0 && key.priv === void 0;
1088
1090
  var isSecretJWK = (key) => key.kty === "oct" && typeof key.k === "string";
1089
1091
 
1090
- // ../../node_modules/jose/dist/webapi/lib/normalize_key.js
1092
+ // node_modules/jose/dist/webapi/lib/normalize_key.js
1091
1093
  var cache;
1092
1094
  var handleJWK = async (key, jwk, alg, freeze = false) => {
1093
1095
  cache ||= /* @__PURE__ */ new WeakMap();
@@ -1258,7 +1260,7 @@ async function normalizeKey(key, alg) {
1258
1260
  throw new Error("unreachable");
1259
1261
  }
1260
1262
 
1261
- // ../../node_modules/jose/dist/webapi/lib/check_key_type.js
1263
+ // node_modules/jose/dist/webapi/lib/check_key_type.js
1262
1264
  var tag = (key) => key?.[Symbol.toStringTag];
1263
1265
  var jwkMatchesOp = (alg, key, usage) => {
1264
1266
  if (key.use !== void 0) {
@@ -1378,7 +1380,7 @@ function checkKeyType(alg, key, usage) {
1378
1380
  }
1379
1381
  }
1380
1382
 
1381
- // ../../node_modules/jose/dist/webapi/lib/subtle_dsa.js
1383
+ // node_modules/jose/dist/webapi/lib/subtle_dsa.js
1382
1384
  function subtleAlgorithm(alg, algorithm) {
1383
1385
  const hash = `SHA-${alg.slice(-3)}`;
1384
1386
  switch (alg) {
@@ -1410,7 +1412,7 @@ function subtleAlgorithm(alg, algorithm) {
1410
1412
  }
1411
1413
  }
1412
1414
 
1413
- // ../../node_modules/jose/dist/webapi/lib/get_sign_verify_key.js
1415
+ // node_modules/jose/dist/webapi/lib/get_sign_verify_key.js
1414
1416
  async function getSigKey(alg, key, usage) {
1415
1417
  if (key instanceof Uint8Array) {
1416
1418
  if (!alg.startsWith("HS")) {
@@ -1422,7 +1424,7 @@ async function getSigKey(alg, key, usage) {
1422
1424
  return key;
1423
1425
  }
1424
1426
 
1425
- // ../../node_modules/jose/dist/webapi/lib/verify.js
1427
+ // node_modules/jose/dist/webapi/lib/verify.js
1426
1428
  async function verify(alg, key, signature, data) {
1427
1429
  const cryptoKey = await getSigKey(alg, key, "verify");
1428
1430
  checkKeyLength(alg, cryptoKey);
@@ -1434,7 +1436,7 @@ async function verify(alg, key, signature, data) {
1434
1436
  }
1435
1437
  }
1436
1438
 
1437
- // ../../node_modules/jose/dist/webapi/jws/flattened/verify.js
1439
+ // node_modules/jose/dist/webapi/jws/flattened/verify.js
1438
1440
  async function flattenedVerify(jws, key, options) {
1439
1441
  if (!isObject(jws)) {
1440
1442
  throw new JWSInvalid("Flattened JWS must be an object");
@@ -1536,7 +1538,7 @@ async function flattenedVerify(jws, key, options) {
1536
1538
  return result;
1537
1539
  }
1538
1540
 
1539
- // ../../node_modules/jose/dist/webapi/jws/compact/verify.js
1541
+ // node_modules/jose/dist/webapi/jws/compact/verify.js
1540
1542
  async function compactVerify(jws, key, options) {
1541
1543
  if (jws instanceof Uint8Array) {
1542
1544
  jws = decoder.decode(jws);
@@ -1556,7 +1558,7 @@ async function compactVerify(jws, key, options) {
1556
1558
  return result;
1557
1559
  }
1558
1560
 
1559
- // ../../node_modules/jose/dist/webapi/lib/jwt_claims_set.js
1561
+ // node_modules/jose/dist/webapi/lib/jwt_claims_set.js
1560
1562
  var epoch = (date) => Math.floor(date.getTime() / 1e3);
1561
1563
  var minute = 60;
1562
1564
  var hour = minute * 60;
@@ -1713,7 +1715,7 @@ function validateClaimsSet(protectedHeader, encodedPayload, options = {}) {
1713
1715
  return payload;
1714
1716
  }
1715
1717
 
1716
- // ../../node_modules/jose/dist/webapi/jwt/verify.js
1718
+ // node_modules/jose/dist/webapi/jwt/verify.js
1717
1719
  async function jwtVerify(jwt, key, options) {
1718
1720
  const verified = await compactVerify(jwt, key, options);
1719
1721
  if (verified.protectedHeader.crit?.includes("b64") && verified.protectedHeader.b64 === false) {
@@ -1727,6 +1729,41 @@ async function jwtVerify(jwt, key, options) {
1727
1729
  return result;
1728
1730
  }
1729
1731
 
1732
+ // src/lib/ids.ts
1733
+ var B58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
1734
+ var B58_MAP = Object.fromEntries([...B58].map((c, i) => [c, i]));
1735
+ function encodeUserId(uuid) {
1736
+ const hex = uuid.replace(/-/g, "");
1737
+ if (hex.length !== 32)
1738
+ throw new Error("Invalid UUID: expected 32 hex chars after stripping dashes");
1739
+ let n = BigInt("0x" + hex);
1740
+ let r = "";
1741
+ while (n > 0n) {
1742
+ r = B58[Number(n % 58n)] + r;
1743
+ n /= 58n;
1744
+ }
1745
+ return `user_${r}`;
1746
+ }
1747
+ function decodeUserId(prefixedId) {
1748
+ if (!prefixedId.startsWith("user_")) return null;
1749
+ const enc = prefixedId.slice(5);
1750
+ if (!enc) return null;
1751
+ let n = 0n;
1752
+ for (const c of enc) {
1753
+ const i = B58_MAP[c] ?? -1;
1754
+ if (i === -1) return null;
1755
+ n = n * 58n + BigInt(i);
1756
+ }
1757
+ const hex = n.toString(16).padStart(32, "0");
1758
+ return [
1759
+ hex.slice(0, 8),
1760
+ hex.slice(8, 12),
1761
+ hex.slice(12, 16),
1762
+ hex.slice(16, 20),
1763
+ hex.slice(20)
1764
+ ].join("-");
1765
+ }
1766
+
1730
1767
  // src/server/index.ts
1731
1768
  function isJwksResponse(data) {
1732
1769
  return typeof data === "object" && data !== null && "keys" in data && Array.isArray(data.keys);
@@ -1735,7 +1772,7 @@ function isAccessTokenPayload(payload) {
1735
1772
  return typeof payload.sub === "string" && typeof payload.email === "string" && typeof payload.app_id === "string" && typeof payload.iat === "number" && typeof payload.exp === "number";
1736
1773
  }
1737
1774
  var jwksCache = null;
1738
- async function getJwks(platformUrl = DEFAULT_PLATFORM_URL) {
1775
+ async function getJwks(platformUrl = `https://${DEFAULT_SDK_API_HOST}`) {
1739
1776
  const now = Date.now();
1740
1777
  if (jwksCache && jwksCache.expiresAt > now) {
1741
1778
  return jwksCache.keys;
@@ -1756,7 +1793,7 @@ async function getJwks(platformUrl = DEFAULT_PLATFORM_URL) {
1756
1793
  return data.keys;
1757
1794
  }
1758
1795
  async function verifyAccessToken(token, options) {
1759
- const platformUrl = options.platformUrl || DEFAULT_PLATFORM_URL;
1796
+ const platformUrl = options.platformUrl || `https://${DEFAULT_SDK_API_HOST}`;
1760
1797
  const keys = await getJwks(platformUrl);
1761
1798
  if (!keys.length) {
1762
1799
  throw new Error("No keys in JWKS");
@@ -1773,6 +1810,7 @@ async function verifyAccessToken(token, options) {
1773
1810
  }
1774
1811
  return {
1775
1812
  sub: payload.sub,
1813
+ pid: payload.pid,
1776
1814
  email: payload.email,
1777
1815
  name: payload.name,
1778
1816
  picture: payload.picture,
@@ -1798,7 +1836,7 @@ function configureServer(config) {
1798
1836
  const secretKey = validateAndSanitizeSecretKey(config.secretKey);
1799
1837
  serverConfig = {
1800
1838
  secretKey,
1801
- platformUrl: (config.platformUrl || DEFAULT_PLATFORM_URL).trim()
1839
+ platformUrl: `https://${DEFAULT_SDK_API_HOST}`.trim()
1802
1840
  };
1803
1841
  }
1804
1842
  function getConfig() {
@@ -1811,7 +1849,7 @@ function getConfig() {
1811
1849
  }
1812
1850
  try {
1813
1851
  const secretKey = validateAndSanitizeSecretKey(rawSecretKey);
1814
- const platformUrl = (process.env.SYLPHX_PLATFORM_URL || DEFAULT_PLATFORM_URL).trim();
1852
+ const platformUrl = `https://${DEFAULT_SDK_API_HOST}`.trim();
1815
1853
  serverConfig = { secretKey, platformUrl };
1816
1854
  return serverConfig;
1817
1855
  } catch (error) {
@@ -1837,10 +1875,11 @@ var auth = (0, import_react.cache)(async () => {
1837
1875
  if (sessionToken && expiresAt && expiresAt > Date.now() + TOKEN_EXPIRY_BUFFER_MS) {
1838
1876
  try {
1839
1877
  const payload = await verifyAccessToken(sessionToken, config);
1878
+ const resolvedUserId = payload.pid ?? payload.sub;
1840
1879
  return {
1841
- userId: payload.sub,
1880
+ userId: resolvedUserId,
1842
1881
  user: user || {
1843
- id: payload.sub,
1882
+ id: resolvedUserId,
1844
1883
  email: payload.email,
1845
1884
  name: payload.name || null,
1846
1885
  image: payload.picture || null,
@@ -1876,7 +1915,7 @@ async function handleCallback2(code) {
1876
1915
  if (!config) {
1877
1916
  throw new Error("Sylphx SDK not configured. Set SYLPHX_SECRET_KEY environment variable.");
1878
1917
  }
1879
- const response = await fetch(`${config.platformUrl}/api/v1/auth/token`, {
1918
+ const response = await fetch(`${config.platformUrl}/v1/auth/token`, {
1880
1919
  method: "POST",
1881
1920
  headers: { "Content-Type": "application/json" },
1882
1921
  body: JSON.stringify({
@@ -1906,7 +1945,7 @@ async function signOut() {
1906
1945
  const { refreshToken } = await getAuthCookies(namespace);
1907
1946
  if (refreshToken) {
1908
1947
  try {
1909
- await fetch(`${config.platformUrl}/api/v1/auth/revoke`, {
1948
+ await fetch(`${config.platformUrl}/v1/auth/revoke`, {
1910
1949
  method: "POST",
1911
1950
  headers: { "Content-Type": "application/json" },
1912
1951
  body: JSON.stringify({
@@ -1967,6 +2006,8 @@ async function getSessionToken() {
1967
2006
  createSylphxMiddleware,
1968
2007
  currentUser,
1969
2008
  currentUserId,
2009
+ decodeUserId,
2010
+ encodeUserId,
1970
2011
  getAuthCookies,
1971
2012
  getAuthorizationUrl,
1972
2013
  getCookieNames,