@tinycloud/sdk-core 3.0.0-beta.11 → 3.0.0-beta.12

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/index.cjs CHANGED
@@ -101,6 +101,7 @@ __export(index_exports, {
101
101
  ED25519_JCS_SIGNATURE_SUITE: () => ED25519_JCS_SIGNATURE_SUITE,
102
102
  EIP191_JCS_SIGNATURE_SUITE: () => EIP191_JCS_SIGNATURE_SUITE,
103
103
  EMAIL_CREDENTIAL_MAX_AGE_SECONDS: () => EMAIL_CREDENTIAL_MAX_AGE_SECONDS,
104
+ EMAIL_DOMAIN_CREDENTIAL_MAX_AGE_SECONDS: () => EMAIL_DOMAIN_CREDENTIAL_MAX_AGE_SECONDS,
104
105
  ENCRYPTION: () => import_bootstrap4.ENCRYPTION,
105
106
  ENCRYPTION_MANIFEST_SPACE: () => ENCRYPTION_MANIFEST_SPACE,
106
107
  ENCRYPTION_NETWORK_URN_PREFIX: () => import_sdk_services8.ENCRYPTION_NETWORK_URN_PREFIX,
@@ -245,8 +246,10 @@ __export(index_exports, {
245
246
  buildPolicyCredentialPresentationV4: () => buildPolicyCredentialPresentationV4,
246
247
  buildSpaceUri: () => buildSpaceUri,
247
248
  canonicalDigest: () => canonicalDigest,
249
+ canonicalEmailDomain: () => canonicalEmailDomain,
248
250
  canonicalHashHex: () => import_sdk_services8.canonicalHashHex,
249
251
  canonicalLocationPayload: () => canonicalLocationPayload,
252
+ canonicalMailbox: () => canonicalMailbox,
250
253
  canonicalOwnerSharePolicy: () => canonicalOwnerSharePolicy,
251
254
  canonicalSignedResponse: () => import_sdk_services8.canonicalSignedResponse,
252
255
  canonicalizeAddress: () => canonicalizeAddress,
@@ -274,6 +277,7 @@ __export(index_exports, {
274
277
  createCapabilityKeyRegistry: () => createCapabilityKeyRegistry,
275
278
  createDelegatedShareKey: () => createDelegatedShareKey,
276
279
  createEmailCredentialRequirement: () => createEmailCredentialRequirement,
280
+ createEmailDomainCredentialRequirement: () => createEmailDomainCredentialRequirement,
277
281
  createHolderBinding: () => createHolderBinding,
278
282
  createInMemoryLocalNodeIdentityStore: () => createInMemoryLocalNodeIdentityStore,
279
283
  createLocalStorageLocalNodeIdentityStore: () => createLocalStorageLocalNodeIdentityStore,
@@ -346,6 +350,7 @@ __export(index_exports, {
346
350
  importPortableDelegation: () => importPortableDelegation,
347
351
  installTinyCloudDebugGlobals: () => import_sdk_services8.installTinyCloudDebugGlobals,
348
352
  intersectShareCapabilities: () => intersectShareCapabilities,
353
+ isCanonicalEmailDomain: () => isCanonicalEmailDomain,
349
354
  isCapabilitySubset: () => isCapabilitySubset,
350
355
  isDigest: () => isDigest,
351
356
  isEvmAddress: () => isEvmAddress,
@@ -356,6 +361,7 @@ __export(index_exports, {
356
361
  jcsCanonicalize: () => jcsCanonicalize,
357
362
  loadManifest: () => loadManifest,
358
363
  locationPayloadForRecord: () => locationPayloadForRecord,
364
+ mailboxBelongsToDomain: () => mailboxBelongsToDomain,
359
365
  makePkhSpaceId: () => makePkhSpaceId,
360
366
  makePublicSpaceId: () => makePublicSpaceId,
361
367
  manifestAbilitiesUnion: () => manifestAbilitiesUnion,
@@ -851,6 +857,7 @@ function holderBindingSigningBytes(binding) {
851
857
 
852
858
  // src/credentials/descriptor.ts
853
859
  var ID = /^[a-z0-9][a-z0-9._-]{0,127}(?:\/v1)?$/;
860
+ var CLAIM_NAME = /^[a-z0-9][A-Za-z0-9._-]{0,127}$/;
854
861
  var STEP_TYPES = /* @__PURE__ */ new Set(["collect_input", "mailbox_otp", "holder_signature"]);
855
862
  var ENDPOINTS = {
856
863
  request: "request",
@@ -931,7 +938,7 @@ function validateCredentialFlowDescriptor(value) {
931
938
  for (const value2 of raw.claims) {
932
939
  const claim = object(value2, "claim");
933
940
  exact(claim, ["name", "matching", "selectiveDisclosure"], "claim");
934
- const name2 = text(claim.name, "claim.name", ID);
941
+ const name2 = text(claim.name, "claim.name", CLAIM_NAME);
935
942
  if (claimNames.has(name2) || claim.matching !== "normalized_exact" || typeof claim.selectiveDisclosure !== "boolean") fail("claim is invalid");
936
943
  claimNames.add(name2);
937
944
  }
@@ -1022,9 +1029,36 @@ function isDigest(value) {
1022
1029
  return typeof value === "string" && /^[A-Za-z0-9_-]{43}$/.test(value);
1023
1030
  }
1024
1031
 
1032
+ // src/credentials/email-domain.ts
1033
+ var LABEL = /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/;
1034
+ function isCanonicalEmailDomain(value) {
1035
+ if (value.length === 0 || value.length > 253) return false;
1036
+ const labels = value.split(".");
1037
+ return labels.length >= 2 && labels.every((label) => LABEL.test(label)) && !/^[0-9]+$/.test(labels.at(-1));
1038
+ }
1039
+ function canonicalEmailDomain(value) {
1040
+ const domain = value.trim().replace(/^@/, "").toLowerCase();
1041
+ if (!/^[\x21-\x7e]+$/.test(domain) || !isCanonicalEmailDomain(domain)) throw new TypeError("email domain must be lowercase ASCII DNS labels (use the xn-- form for international domains)");
1042
+ return domain;
1043
+ }
1044
+ function canonicalMailbox(value) {
1045
+ const email = value.trim().toLowerCase();
1046
+ const at = email.indexOf("@");
1047
+ if (at <= 0 || at !== email.lastIndexOf("@")) return void 0;
1048
+ const local = email.slice(0, at);
1049
+ const domain = email.slice(at + 1);
1050
+ if (local.length > 64 || !/^[a-z0-9#$&'*+/=?^_`{|}~-]+(?:\.[a-z0-9#$&'*+/=?^_`{|}~-]+)*$/.test(local) || !isCanonicalEmailDomain(domain)) return void 0;
1051
+ return Object.freeze({ email, domain });
1052
+ }
1053
+ function mailboxBelongsToDomain(mailbox, domain) {
1054
+ return canonicalMailbox(mailbox)?.domain === domain && isCanonicalEmailDomain(domain);
1055
+ }
1056
+
1025
1057
  // src/credentials/requirement.ts
1026
1058
  var ID2 = /^[a-z0-9][a-z0-9._-]{0,127}(?:\/v1)?$/;
1027
1059
  var EMAIL_CREDENTIAL_MAX_AGE_SECONDS = 3600;
1060
+ var EMAIL_DOMAIN_CREDENTIAL_MAX_AGE_SECONDS = 300;
1061
+ var CLAIM_NAME2 = /^[a-z0-9][A-Za-z0-9._-]{0,127}$/;
1028
1062
  function createEmailCredentialRequirement(input) {
1029
1063
  return validateCredentialRequirement({
1030
1064
  type: "TinyCloudCredentialRequirement",
@@ -1035,6 +1069,17 @@ function createEmailCredentialRequirement(input) {
1035
1069
  maxAgeSeconds: EMAIL_CREDENTIAL_MAX_AGE_SECONDS
1036
1070
  });
1037
1071
  }
1072
+ function createEmailDomainCredentialRequirement(input) {
1073
+ if (!isCanonicalEmailDomain(input.domain)) throw new CredentialError("UNSUPPORTED_PROFILE", "Email domain is not canonical");
1074
+ return validateCredentialRequirement({
1075
+ type: "TinyCloudCredentialRequirement",
1076
+ version: 1,
1077
+ profile: input.profile,
1078
+ credentialType: input.credentialType,
1079
+ claims: { emailDomain: input.domain },
1080
+ maxAgeSeconds: EMAIL_DOMAIN_CREDENTIAL_MAX_AGE_SECONDS
1081
+ });
1082
+ }
1038
1083
  function validateCredentialRequirement(value) {
1039
1084
  if (typeof value !== "object" || value === null || Array.isArray(value)) throw new CredentialError("UNSUPPORTED_PROFILE", "Credential requirement is invalid");
1040
1085
  const raw = value;
@@ -1048,7 +1093,7 @@ function validateCredentialRequirement(value) {
1048
1093
  if (typeof raw.claims !== "object" || raw.claims === null || Array.isArray(raw.claims)) throw new CredentialError("UNSUPPORTED_PROFILE", "Credential claims are invalid");
1049
1094
  const claims = {};
1050
1095
  for (const [key, value2] of Object.entries(raw.claims).sort(([a], [b]) => a.localeCompare(b))) {
1051
- if (!ID2.test(key) || typeof value2 !== "string" || value2.length === 0 || value2.length > 4096) throw new CredentialError("UNSUPPORTED_PROFILE", "Credential claim is invalid");
1096
+ if (!CLAIM_NAME2.test(key) || typeof value2 !== "string" || value2.length === 0 || value2.length > 4096) throw new CredentialError("UNSUPPORTED_PROFILE", "Credential claim is invalid");
1052
1097
  claims[key] = value2;
1053
1098
  }
1054
1099
  if (raw.maxAgeSeconds !== void 0 && (!Number.isSafeInteger(raw.maxAgeSeconds) || raw.maxAgeSeconds < 1)) throw new CredentialError("UNSUPPORTED_PROFILE", "Credential freshness is invalid");