@cedros/login-react 0.0.1

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.
Files changed (200) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1183 -0
  3. package/dist/EmailRegisterForm-D_uCEdX9.cjs +1 -0
  4. package/dist/EmailRegisterForm-D_uCEdX9.cjs.map +1 -0
  5. package/dist/EmailRegisterForm-m3rX3A6X.js +2923 -0
  6. package/dist/EmailRegisterForm-m3rX3A6X.js.map +1 -0
  7. package/dist/ErrorMessage-Bm1j5mBT.js +2042 -0
  8. package/dist/ErrorMessage-Bm1j5mBT.js.map +1 -0
  9. package/dist/ErrorMessage-CntMyn93.cjs +1 -0
  10. package/dist/ErrorMessage-CntMyn93.cjs.map +1 -0
  11. package/dist/GoogleLoginButton-CJNJ-THo.cjs +1 -0
  12. package/dist/GoogleLoginButton-CJNJ-THo.cjs.map +1 -0
  13. package/dist/GoogleLoginButton-CvDoOc-0.js +227 -0
  14. package/dist/GoogleLoginButton-CvDoOc-0.js.map +1 -0
  15. package/dist/SolanaLoginButton-BlSgPW50.cjs +1 -0
  16. package/dist/SolanaLoginButton-BlSgPW50.cjs.map +1 -0
  17. package/dist/SolanaLoginButton-h32xN2PQ.js +261 -0
  18. package/dist/SolanaLoginButton-h32xN2PQ.js.map +1 -0
  19. package/dist/assets/argon2Worker-Bi5TuQvD.js +1 -0
  20. package/dist/assets/argon2Worker-Bi5TuQvD.js.map +1 -0
  21. package/dist/components/LoginButton.d.ts +23 -0
  22. package/dist/components/LoginForm.d.ts +9 -0
  23. package/dist/components/LoginModal.d.ts +9 -0
  24. package/dist/components/admin/AdminUserDetail.d.ts +21 -0
  25. package/dist/components/admin/AdminUserList.d.ts +25 -0
  26. package/dist/components/admin/CedrosAdminDashboard.d.ts +48 -0
  27. package/dist/components/admin/SystemSettings.d.ts +19 -0
  28. package/dist/components/apple/AppleLoginButton.d.ts +29 -0
  29. package/dist/components/deposit/CreditBalance.d.ts +19 -0
  30. package/dist/components/deposit/DepositFlow.d.ts +118 -0
  31. package/dist/components/deposit/FeeConfigDisplay.d.ts +15 -0
  32. package/dist/components/deposit/History.d.ts +21 -0
  33. package/dist/components/deposit/TieredAmountSlider.d.ts +19 -0
  34. package/dist/components/deposit/TokenSelector.d.ts +23 -0
  35. package/dist/components/deposit/admin/AdminDepositList.d.ts +21 -0
  36. package/dist/components/deposit/admin/AdminDepositStats.d.ts +15 -0
  37. package/dist/components/deposit/admin/AdminPrivacyPeriodDeposits.d.ts +19 -0
  38. package/dist/components/deposit/admin/AdminWithdrawalHistory.d.ts +19 -0
  39. package/dist/components/deposit/admin/AdminWithdrawalQueue.d.ts +23 -0
  40. package/dist/components/deposit/admin/PrivacySystemStatus.d.ts +15 -0
  41. package/dist/components/deposit/admin/index.d.ts +17 -0
  42. package/dist/components/deposit/index.d.ts +12 -0
  43. package/dist/components/deposit/tierUtils.d.ts +8 -0
  44. package/dist/components/deposit/tokens.d.ts +19 -0
  45. package/dist/components/email/EmailLoginForm.d.ts +11 -0
  46. package/dist/components/email/EmailRegisterForm.d.ts +14 -0
  47. package/dist/components/email/ForgotPasswordForm.d.ts +17 -0
  48. package/dist/components/email/PasswordInput.d.ts +14 -0
  49. package/dist/components/email/ResetPasswordForm.d.ts +22 -0
  50. package/dist/components/google/GoogleLoginButton.d.ts +12 -0
  51. package/dist/components/invites/InviteForm.d.ts +38 -0
  52. package/dist/components/invites/InviteList.d.ts +40 -0
  53. package/dist/components/members/MemberList.d.ts +47 -0
  54. package/dist/components/org/CreateOrgForm.d.ts +7 -0
  55. package/dist/components/org/OrgAvatar.d.ts +7 -0
  56. package/dist/components/org/OrgListView.d.ts +9 -0
  57. package/dist/components/org/OrgSelector.d.ts +51 -0
  58. package/dist/components/org/OrgSwitcher.d.ts +47 -0
  59. package/dist/components/org/icons.d.ts +8 -0
  60. package/dist/components/sessions/SessionList.d.ts +33 -0
  61. package/dist/components/shared/ErrorBoundary.d.ts +38 -0
  62. package/dist/components/shared/ErrorMessage.d.ts +14 -0
  63. package/dist/components/shared/LoadingSpinner.d.ts +16 -0
  64. package/dist/components/solana/SolanaLoginButton.d.ts +49 -0
  65. package/dist/components/templates/FullPageLayout.d.ts +40 -0
  66. package/dist/components/templates/SplitPageLayout.d.ts +44 -0
  67. package/dist/components/templates/index.d.ts +4 -0
  68. package/dist/components/totp/OtpInput.d.ts +32 -0
  69. package/dist/components/totp/QrCode.d.ts +21 -0
  70. package/dist/components/totp/TotpSettings.d.ts +38 -0
  71. package/dist/components/totp/TotpSetup.d.ts +23 -0
  72. package/dist/components/totp/TotpVerify.d.ts +25 -0
  73. package/dist/components/totp/index.d.ts +10 -0
  74. package/dist/components/wallet/CapabilityWarning.d.ts +11 -0
  75. package/dist/components/wallet/PasskeyPrompt.d.ts +34 -0
  76. package/dist/components/wallet/RecoveryPhraseDisplay.d.ts +18 -0
  77. package/dist/components/wallet/RecoveryPhraseInput.d.ts +21 -0
  78. package/dist/components/wallet/WalletAddressRow.d.ts +10 -0
  79. package/dist/components/wallet/WalletEnrollment.d.ts +15 -0
  80. package/dist/components/wallet/WalletManager.d.ts +9 -0
  81. package/dist/components/wallet/WalletRecovery.d.ts +19 -0
  82. package/dist/components/wallet/WalletStatus.d.ts +28 -0
  83. package/dist/components/wallet/WalletUnlock.d.ts +23 -0
  84. package/dist/components/wallet/index.d.ts +23 -0
  85. package/dist/components/webauthn/PasskeyLoginButton.d.ts +8 -0
  86. package/dist/context/CedrosLoginContext.d.ts +24 -0
  87. package/dist/context/CedrosLoginProvider.d.ts +17 -0
  88. package/dist/context/EmbeddedWalletExposure.d.ts +19 -0
  89. package/dist/context/useCedrosLogin.d.ts +12 -0
  90. package/dist/crypto/aesGcm.d.ts +89 -0
  91. package/dist/crypto/argon2.d.ts +65 -0
  92. package/dist/crypto/argon2Worker.d.ts +1 -0
  93. package/dist/crypto/argon2WorkerClient.d.ts +28 -0
  94. package/dist/crypto/bip39.d.ts +106 -0
  95. package/dist/crypto/capabilities.d.ts +35 -0
  96. package/dist/crypto/entropy.d.ts +56 -0
  97. package/dist/crypto/hkdf.d.ts +38 -0
  98. package/dist/crypto/index.d.ts +30 -0
  99. package/dist/crypto/secureWipe.d.ts +90 -0
  100. package/dist/crypto/shamir.d.ts +52 -0
  101. package/dist/crypto/solanaKeypair.d.ts +63 -0
  102. package/dist/crypto/types.d.ts +134 -0
  103. package/dist/crypto/webauthnPrf.d.ts +118 -0
  104. package/dist/email-only.cjs +1 -0
  105. package/dist/email-only.cjs.map +1 -0
  106. package/dist/email-only.d.ts +16 -0
  107. package/dist/email-only.js +15 -0
  108. package/dist/email-only.js.map +1 -0
  109. package/dist/google-only.cjs +1 -0
  110. package/dist/google-only.cjs.map +1 -0
  111. package/dist/google-only.d.ts +13 -0
  112. package/dist/google-only.js +11 -0
  113. package/dist/google-only.js.map +1 -0
  114. package/dist/hooks/useAdminDeposits.d.ts +10 -0
  115. package/dist/hooks/useAdminUsers.d.ts +28 -0
  116. package/dist/hooks/useAppleAuth.d.ts +52 -0
  117. package/dist/hooks/useAuth.d.ts +34 -0
  118. package/dist/hooks/useAuthSession.d.ts +19 -0
  119. package/dist/hooks/useAuthorize.d.ts +62 -0
  120. package/dist/hooks/useCredits.d.ts +11 -0
  121. package/dist/hooks/useDeposit.d.ts +16 -0
  122. package/dist/hooks/useEmailAuth.d.ts +60 -0
  123. package/dist/hooks/useGoogleAuth.d.ts +67 -0
  124. package/dist/hooks/useInstantLink.d.ts +42 -0
  125. package/dist/hooks/useInvites.d.ts +57 -0
  126. package/dist/hooks/useMembers.d.ts +52 -0
  127. package/dist/hooks/useOrgs.d.ts +49 -0
  128. package/dist/hooks/usePasswordReset.d.ts +32 -0
  129. package/dist/hooks/usePendingRecovery.d.ts +34 -0
  130. package/dist/hooks/useRateLimiter.d.ts +58 -0
  131. package/dist/hooks/useSessions.d.ts +45 -0
  132. package/dist/hooks/useSolanaAuth.d.ts +30 -0
  133. package/dist/hooks/useSystemSettings.d.ts +47 -0
  134. package/dist/hooks/useThemeManager.d.ts +11 -0
  135. package/dist/hooks/useTotp.d.ts +52 -0
  136. package/dist/hooks/useTotpVerify.d.ts +38 -0
  137. package/dist/hooks/useTransactionSigning.d.ts +45 -0
  138. package/dist/hooks/useWallet.d.ts +10 -0
  139. package/dist/hooks/useWalletDiscovery.d.ts +24 -0
  140. package/dist/hooks/useWalletEnrollment.d.ts +9 -0
  141. package/dist/hooks/useWalletMaterial.d.ts +10 -0
  142. package/dist/hooks/useWalletRecovery.d.ts +9 -0
  143. package/dist/hooks/useWalletSigning.d.ts +31 -0
  144. package/dist/hooks/useWebAuthn.d.ts +25 -0
  145. package/dist/i18n/I18nProvider.d.ts +16 -0
  146. package/dist/i18n/context.d.ts +6 -0
  147. package/dist/i18n/index.d.ts +5 -0
  148. package/dist/i18n/translations.d.ts +66 -0
  149. package/dist/i18n/useI18n.d.ts +9 -0
  150. package/dist/index.cjs +2061 -0
  151. package/dist/index.cjs.map +1 -0
  152. package/dist/index.d.ts +126 -0
  153. package/dist/index.js +14910 -0
  154. package/dist/index.js.map +1 -0
  155. package/dist/login-react.css +1 -0
  156. package/dist/solana-only.cjs +1 -0
  157. package/dist/solana-only.cjs.map +1 -0
  158. package/dist/solana-only.d.ts +13 -0
  159. package/dist/solana-only.js +11 -0
  160. package/dist/solana-only.js.map +1 -0
  161. package/dist/style.cjs +1 -0
  162. package/dist/style.cjs.map +1 -0
  163. package/dist/style.js +1 -0
  164. package/dist/style.js.map +1 -0
  165. package/dist/types/adminUser.d.ts +112 -0
  166. package/dist/types/auth.d.ts +122 -0
  167. package/dist/types/config.d.ts +266 -0
  168. package/dist/types/deposit.d.ts +488 -0
  169. package/dist/types/index.d.ts +11 -0
  170. package/dist/types/invite.d.ts +71 -0
  171. package/dist/types/member.d.ts +45 -0
  172. package/dist/types/org.d.ts +101 -0
  173. package/dist/types/session.d.ts +28 -0
  174. package/dist/types/systemSettings.d.ts +81 -0
  175. package/dist/types/totp.d.ts +52 -0
  176. package/dist/types/wallet.d.ts +309 -0
  177. package/dist/utils/adminUserApi.d.ts +51 -0
  178. package/dist/utils/apiClient.d.ts +78 -0
  179. package/dist/utils/cryptoShim.d.ts +17 -0
  180. package/dist/utils/csrf.d.ts +1 -0
  181. package/dist/utils/deviceDetection.d.ts +17 -0
  182. package/dist/utils/embeddedWallet.d.ts +75 -0
  183. package/dist/utils/inviteApi.d.ts +31 -0
  184. package/dist/utils/memberApi.d.ts +23 -0
  185. package/dist/utils/orgApi.d.ts +36 -0
  186. package/dist/utils/sanitization.d.ts +66 -0
  187. package/dist/utils/sessionApi.d.ts +16 -0
  188. package/dist/utils/silentWalletEnroll.d.ts +41 -0
  189. package/dist/utils/systemSettingsApi.d.ts +18 -0
  190. package/dist/utils/tabSync.d.ts +46 -0
  191. package/dist/utils/tokenManager.d.ts +107 -0
  192. package/dist/utils/unlockCredential.d.ts +5 -0
  193. package/dist/utils/validation.d.ts +48 -0
  194. package/dist/utils/walletDetection.d.ts +23 -0
  195. package/dist/utils/webauthnJson.d.ts +21 -0
  196. package/dist/validation-BeXIfuHB.cjs +1 -0
  197. package/dist/validation-BeXIfuHB.cjs.map +1 -0
  198. package/dist/validation-BebL7hMF.js +56 -0
  199. package/dist/validation-BebL7hMF.js.map +1 -0
  200. package/package.json +109 -0
@@ -0,0 +1,21 @@
1
+ type Base64UrlString = string;
2
+ export declare function base64UrlToArrayBuffer(b64url: Base64UrlString): ArrayBuffer;
3
+ export declare function arrayBufferToBase64Url(buffer: ArrayBuffer): Base64UrlString;
4
+ export type ServerCreationOptions = {
5
+ publicKey: Record<string, unknown>;
6
+ };
7
+ export declare function parseCreationOptionsFromServer(options: ServerCreationOptions): PublicKeyCredentialCreationOptions;
8
+ export type ServerRequestOptions = {
9
+ publicKey: Record<string, unknown>;
10
+ };
11
+ export declare function parseRequestOptionsFromServer(options: ServerRequestOptions): PublicKeyCredentialRequestOptions;
12
+ export type PublicKeyCredentialJSON = {
13
+ id: string;
14
+ rawId: string;
15
+ type: string;
16
+ authenticatorAttachment?: string;
17
+ clientExtensionResults?: AuthenticationExtensionsClientOutputs;
18
+ response: Record<string, unknown>;
19
+ };
20
+ export declare function credentialToServerJson(cred: PublicKeyCredential): PublicKeyCredentialJSON;
21
+ export {};
@@ -0,0 +1 @@
1
+ "use strict";const c=/[!@#$%^&*()_+\-=[\]{}|;':",./<>?`~\\]/;function o(e){const s={},a=e.length>=10,t=/[A-Z]/.test(e),n=/[a-z]/.test(e),i=/\d/.test(e),f=c.test(e);let r=0;a?r++:s.length="At least 10 characters",t?r++:s.uppercase="At least 1 uppercase letter",n?r++:s.lowercase="At least 1 lowercase letter",i?r++:s.number="At least 1 number",f?r++:s.special="At least 1 special character (@$!%*?&#^())";let l;return r<=2?l="weak":r===3?l="fair":r===4?l="good":l="strong",{isValid:Object.keys(s).length===0,errors:s,strength:l}}const u=new Set(["con","cmo","ocm","cm","vom","xom","cpm","clm","ney","met","bet","nrt","ogr","rog","prg","irg","edi","rdu"]);function h(e){if(!e||typeof e!="string"||e.length>254||e.includes(" "))return!1;const s=e.split("@");if(s.length!==2)return!1;const[a,t]=s;if(!a||a.length>64||a.startsWith(".")||a.endsWith(".")||!t||t.length>253||!t.includes(".")||t.startsWith(".")||t.endsWith(".")||t.startsWith("-")||t.endsWith("-"))return!1;for(const i of t.split("."))if(i.startsWith("-")||i.endsWith("-"))return!1;const n=t.split(".").pop();return!(!n||n.length<2||!/^[a-zA-Z]+$/.test(n)||u.has(n.toLowerCase())||!/^[a-zA-Z0-9.-]+$/.test(t)||!/^[a-zA-Z0-9._\-+!]+$/.test(a))}const g=/^[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]+$/;function d(e){return e.length<43||e.length>44?!1:g.test(e)}exports.validateEmail=h;exports.validatePassword=o;exports.validateSolanaPublicKey=d;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation-BeXIfuHB.cjs","sources":["../src/utils/validation.ts"],"sourcesContent":["import type { PasswordValidation } from '../types';\n\n/**\n * Allowed special characters for password validation (F-07)\n *\n * This explicit list prevents spaces, tabs, and non-printable characters\n * from counting as \"special\" (H-06 fix). Characters included:\n * - Punctuation: ! @ # $ % ^ & * ( ) _ + - = [ ] { } | ; ' : \" , . / < > ? ` ~\n * - Escape character: backslash\n */\nconst SPECIAL_CHARS_PATTERN = /[!@#$%^&*()_+\\-=[\\]{}|;':\",./<>?`~\\\\]/;\n\n/**\n * Password validation rules:\n * - Minimum 10 characters\n * - At least 1 uppercase letter (A-Z)\n * - At least 1 lowercase letter (a-z)\n * - At least 1 number (0-9)\n * - At least 1 special character (@$!%*?&#^())\n *\n * Note: All checks are performed regardless of early failures to prevent\n * timing attacks that could reveal which requirements are met.\n */\nexport function validatePassword(password: string): PasswordValidation {\n const errors: PasswordValidation['errors'] = {};\n\n // Perform ALL checks first (constant-time approach to prevent timing attacks)\n const hasLength = password.length >= 10;\n const hasUppercase = /[A-Z]/.test(password);\n const hasLowercase = /[a-z]/.test(password);\n const hasNumber = /\\d/.test(password);\n // H-06: Use explicit special character list (see SPECIAL_CHARS_PATTERN)\n const hasSpecial = SPECIAL_CHARS_PATTERN.test(password);\n\n // Count criteria met\n let criteriaMetCount = 0;\n\n // Then assign errors based on results\n if (hasLength) {\n criteriaMetCount++;\n } else {\n errors.length = 'At least 10 characters';\n }\n\n if (hasUppercase) {\n criteriaMetCount++;\n } else {\n errors.uppercase = 'At least 1 uppercase letter';\n }\n\n if (hasLowercase) {\n criteriaMetCount++;\n } else {\n errors.lowercase = 'At least 1 lowercase letter';\n }\n\n if (hasNumber) {\n criteriaMetCount++;\n } else {\n errors.number = 'At least 1 number';\n }\n\n if (hasSpecial) {\n criteriaMetCount++;\n } else {\n errors.special = 'At least 1 special character (@$!%*?&#^())';\n }\n\n // Calculate strength\n let strength: PasswordValidation['strength'];\n if (criteriaMetCount <= 2) {\n strength = 'weak';\n } else if (criteriaMetCount === 3) {\n strength = 'fair';\n } else if (criteriaMetCount === 4) {\n strength = 'good';\n } else {\n strength = 'strong';\n }\n\n return {\n isValid: Object.keys(errors).length === 0,\n errors,\n strength,\n };\n}\n\nconst TYPO_TLDS = new Set([\n 'con',\n 'cmo',\n 'ocm',\n 'cm',\n 'vom',\n 'xom',\n 'cpm',\n 'clm',\n 'ney',\n 'met',\n 'bet',\n 'nrt',\n 'ogr',\n 'rog',\n 'prg',\n 'irg',\n 'edi',\n 'rdu',\n]);\n\n/**\n * Validate email format with robust validation.\n *\n * Validates:\n * - Proper format with @ symbol\n * - Valid characters in local and domain parts\n * - Domain must have at least one dot (TLD required)\n * - Maximum length per RFC 5321\n *\n * UI-13: Note on case normalization - This function validates format only,\n * it does NOT normalize case. Per RFC 5321, local-part is technically\n * case-sensitive (though most providers ignore case). Callers should\n * normalize emails (e.g., toLowerCase) before API calls and storage.\n *\n * @param email - The email address to validate\n * @returns true if the email format is valid\n */\nexport function validateEmail(email: string): boolean {\n // Check basic constraints\n if (!email || typeof email !== 'string') {\n return false;\n }\n\n if (email.length > 254) {\n return false;\n }\n\n if (email.includes(' ')) {\n return false;\n }\n\n const parts = email.split('@');\n if (parts.length !== 2) {\n return false;\n }\n\n const [local, domain] = parts;\n if (!local || local.length > 64) {\n return false;\n }\n\n if (local.startsWith('.') || local.endsWith('.')) {\n return false;\n }\n\n if (!domain || domain.length > 253) {\n return false;\n }\n\n if (!domain.includes('.')) {\n return false;\n }\n\n if (\n domain.startsWith('.') ||\n domain.endsWith('.') ||\n domain.startsWith('-') ||\n domain.endsWith('-')\n ) {\n return false;\n }\n\n for (const label of domain.split('.')) {\n if (label.startsWith('-') || label.endsWith('-')) {\n return false;\n }\n }\n\n const tld = domain.split('.').pop();\n if (!tld || tld.length < 2) {\n return false;\n }\n\n if (!/^[a-zA-Z]+$/.test(tld)) {\n return false;\n }\n\n if (TYPO_TLDS.has(tld.toLowerCase())) {\n return false;\n }\n\n if (!/^[a-zA-Z0-9.-]+$/.test(domain)) {\n return false;\n }\n\n if (!/^[a-zA-Z0-9._\\-+!]+$/.test(local)) {\n return false;\n }\n\n return true;\n}\n\n/**\n * Valid Base58 characters (excludes 0, O, I, l to avoid ambiguity)\n */\nconst BASE58_ALPHABET = /^[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]+$/;\n\n/**\n * Validate Solana public key format.\n *\n * A valid Solana public key:\n * - Is 43-44 characters long (base58 encoding of 32 bytes)\n * - Contains only valid base58 characters\n *\n * @param publicKey - The public key string to validate\n * @returns true if the public key format is valid\n *\n * @example\n * ```ts\n * validateSolanaPublicKey('DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263') // true\n * validateSolanaPublicKey('invalid') // false\n * ```\n */\nexport function validateSolanaPublicKey(publicKey: string): boolean {\n // Check length (base58 encoding of 32 bytes is 43-44 chars)\n if (publicKey.length < 43 || publicKey.length > 44) {\n return false;\n }\n\n // Check for valid base58 characters only\n return BASE58_ALPHABET.test(publicKey);\n}\n"],"names":["SPECIAL_CHARS_PATTERN","validatePassword","password","errors","hasLength","hasUppercase","hasLowercase","hasNumber","hasSpecial","criteriaMetCount","strength","TYPO_TLDS","validateEmail","email","parts","local","domain","label","tld","BASE58_ALPHABET","validateSolanaPublicKey","publicKey"],"mappings":"aAUA,MAAMA,EAAwB,wCAavB,SAASC,EAAiBC,EAAsC,CACrE,MAAMC,EAAuC,CAAA,EAGvCC,EAAYF,EAAS,QAAU,GAC/BG,EAAe,QAAQ,KAAKH,CAAQ,EACpCI,EAAe,QAAQ,KAAKJ,CAAQ,EACpCK,EAAY,KAAK,KAAKL,CAAQ,EAE9BM,EAAaR,EAAsB,KAAKE,CAAQ,EAGtD,IAAIO,EAAmB,EAGnBL,EACFK,IAEAN,EAAO,OAAS,yBAGdE,EACFI,IAEAN,EAAO,UAAY,8BAGjBG,EACFG,IAEAN,EAAO,UAAY,8BAGjBI,EACFE,IAEAN,EAAO,OAAS,oBAGdK,EACFC,IAEAN,EAAO,QAAU,6CAInB,IAAIO,EACJ,OAAID,GAAoB,EACtBC,EAAW,OACFD,IAAqB,EAC9BC,EAAW,OACFD,IAAqB,EAC9BC,EAAW,OAEXA,EAAW,SAGN,CACL,QAAS,OAAO,KAAKP,CAAM,EAAE,SAAW,EACxC,OAAAA,EACA,SAAAO,CAAA,CAEJ,CAEA,MAAMC,MAAgB,IAAI,CACxB,MACA,MACA,MACA,KACA,MACA,MACA,MACA,MACA,MACA,MACA,MACA,MACA,MACA,MACA,MACA,MACA,MACA,KACF,CAAC,EAmBM,SAASC,EAAcC,EAAwB,CAUpD,GARI,CAACA,GAAS,OAAOA,GAAU,UAI3BA,EAAM,OAAS,KAIfA,EAAM,SAAS,GAAG,EACpB,MAAO,GAGT,MAAMC,EAAQD,EAAM,MAAM,GAAG,EAC7B,GAAIC,EAAM,SAAW,EACnB,MAAO,GAGT,KAAM,CAACC,EAAOC,CAAM,EAAIF,EAiBxB,GAhBI,CAACC,GAASA,EAAM,OAAS,IAIzBA,EAAM,WAAW,GAAG,GAAKA,EAAM,SAAS,GAAG,GAI3C,CAACC,GAAUA,EAAO,OAAS,KAI3B,CAACA,EAAO,SAAS,GAAG,GAKtBA,EAAO,WAAW,GAAG,GACrBA,EAAO,SAAS,GAAG,GACnBA,EAAO,WAAW,GAAG,GACrBA,EAAO,SAAS,GAAG,EAEnB,MAAO,GAGT,UAAWC,KAASD,EAAO,MAAM,GAAG,EAClC,GAAIC,EAAM,WAAW,GAAG,GAAKA,EAAM,SAAS,GAAG,EAC7C,MAAO,GAIX,MAAMC,EAAMF,EAAO,MAAM,GAAG,EAAE,IAAA,EAiB9B,MAhBI,GAACE,GAAOA,EAAI,OAAS,GAIrB,CAAC,cAAc,KAAKA,CAAG,GAIvBP,EAAU,IAAIO,EAAI,YAAA,CAAa,GAI/B,CAAC,mBAAmB,KAAKF,CAAM,GAI/B,CAAC,uBAAuB,KAAKD,CAAK,EAKxC,CAKA,MAAMI,EAAkB,kEAkBjB,SAASC,EAAwBC,EAA4B,CAElE,OAAIA,EAAU,OAAS,IAAMA,EAAU,OAAS,GACvC,GAIFF,EAAgB,KAAKE,CAAS,CACvC"}
@@ -0,0 +1,56 @@
1
+ const c = /[!@#$%^&*()_+\-=[\]{}|;':",./<>?`~\\]/;
2
+ function h(e) {
3
+ const s = {}, n = e.length >= 10, t = /[A-Z]/.test(e), a = /[a-z]/.test(e), i = /\d/.test(e), f = c.test(e);
4
+ let r = 0;
5
+ n ? r++ : s.length = "At least 10 characters", t ? r++ : s.uppercase = "At least 1 uppercase letter", a ? r++ : s.lowercase = "At least 1 lowercase letter", i ? r++ : s.number = "At least 1 number", f ? r++ : s.special = "At least 1 special character (@$!%*?&#^())";
6
+ let l;
7
+ return r <= 2 ? l = "weak" : r === 3 ? l = "fair" : r === 4 ? l = "good" : l = "strong", {
8
+ isValid: Object.keys(s).length === 0,
9
+ errors: s,
10
+ strength: l
11
+ };
12
+ }
13
+ const o = /* @__PURE__ */ new Set([
14
+ "con",
15
+ "cmo",
16
+ "ocm",
17
+ "cm",
18
+ "vom",
19
+ "xom",
20
+ "cpm",
21
+ "clm",
22
+ "ney",
23
+ "met",
24
+ "bet",
25
+ "nrt",
26
+ "ogr",
27
+ "rog",
28
+ "prg",
29
+ "irg",
30
+ "edi",
31
+ "rdu"
32
+ ]);
33
+ function g(e) {
34
+ if (!e || typeof e != "string" || e.length > 254 || e.includes(" "))
35
+ return !1;
36
+ const s = e.split("@");
37
+ if (s.length !== 2)
38
+ return !1;
39
+ const [n, t] = s;
40
+ if (!n || n.length > 64 || n.startsWith(".") || n.endsWith(".") || !t || t.length > 253 || !t.includes(".") || t.startsWith(".") || t.endsWith(".") || t.startsWith("-") || t.endsWith("-"))
41
+ return !1;
42
+ for (const i of t.split("."))
43
+ if (i.startsWith("-") || i.endsWith("-"))
44
+ return !1;
45
+ const a = t.split(".").pop();
46
+ return !(!a || a.length < 2 || !/^[a-zA-Z]+$/.test(a) || o.has(a.toLowerCase()) || !/^[a-zA-Z0-9.-]+$/.test(t) || !/^[a-zA-Z0-9._\-+!]+$/.test(n));
47
+ }
48
+ const u = /^[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]+$/;
49
+ function A(e) {
50
+ return e.length < 43 || e.length > 44 ? !1 : u.test(e);
51
+ }
52
+ export {
53
+ A as a,
54
+ g as b,
55
+ h as v
56
+ };
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation-BebL7hMF.js","sources":["../src/utils/validation.ts"],"sourcesContent":["import type { PasswordValidation } from '../types';\n\n/**\n * Allowed special characters for password validation (F-07)\n *\n * This explicit list prevents spaces, tabs, and non-printable characters\n * from counting as \"special\" (H-06 fix). Characters included:\n * - Punctuation: ! @ # $ % ^ & * ( ) _ + - = [ ] { } | ; ' : \" , . / < > ? ` ~\n * - Escape character: backslash\n */\nconst SPECIAL_CHARS_PATTERN = /[!@#$%^&*()_+\\-=[\\]{}|;':\",./<>?`~\\\\]/;\n\n/**\n * Password validation rules:\n * - Minimum 10 characters\n * - At least 1 uppercase letter (A-Z)\n * - At least 1 lowercase letter (a-z)\n * - At least 1 number (0-9)\n * - At least 1 special character (@$!%*?&#^())\n *\n * Note: All checks are performed regardless of early failures to prevent\n * timing attacks that could reveal which requirements are met.\n */\nexport function validatePassword(password: string): PasswordValidation {\n const errors: PasswordValidation['errors'] = {};\n\n // Perform ALL checks first (constant-time approach to prevent timing attacks)\n const hasLength = password.length >= 10;\n const hasUppercase = /[A-Z]/.test(password);\n const hasLowercase = /[a-z]/.test(password);\n const hasNumber = /\\d/.test(password);\n // H-06: Use explicit special character list (see SPECIAL_CHARS_PATTERN)\n const hasSpecial = SPECIAL_CHARS_PATTERN.test(password);\n\n // Count criteria met\n let criteriaMetCount = 0;\n\n // Then assign errors based on results\n if (hasLength) {\n criteriaMetCount++;\n } else {\n errors.length = 'At least 10 characters';\n }\n\n if (hasUppercase) {\n criteriaMetCount++;\n } else {\n errors.uppercase = 'At least 1 uppercase letter';\n }\n\n if (hasLowercase) {\n criteriaMetCount++;\n } else {\n errors.lowercase = 'At least 1 lowercase letter';\n }\n\n if (hasNumber) {\n criteriaMetCount++;\n } else {\n errors.number = 'At least 1 number';\n }\n\n if (hasSpecial) {\n criteriaMetCount++;\n } else {\n errors.special = 'At least 1 special character (@$!%*?&#^())';\n }\n\n // Calculate strength\n let strength: PasswordValidation['strength'];\n if (criteriaMetCount <= 2) {\n strength = 'weak';\n } else if (criteriaMetCount === 3) {\n strength = 'fair';\n } else if (criteriaMetCount === 4) {\n strength = 'good';\n } else {\n strength = 'strong';\n }\n\n return {\n isValid: Object.keys(errors).length === 0,\n errors,\n strength,\n };\n}\n\nconst TYPO_TLDS = new Set([\n 'con',\n 'cmo',\n 'ocm',\n 'cm',\n 'vom',\n 'xom',\n 'cpm',\n 'clm',\n 'ney',\n 'met',\n 'bet',\n 'nrt',\n 'ogr',\n 'rog',\n 'prg',\n 'irg',\n 'edi',\n 'rdu',\n]);\n\n/**\n * Validate email format with robust validation.\n *\n * Validates:\n * - Proper format with @ symbol\n * - Valid characters in local and domain parts\n * - Domain must have at least one dot (TLD required)\n * - Maximum length per RFC 5321\n *\n * UI-13: Note on case normalization - This function validates format only,\n * it does NOT normalize case. Per RFC 5321, local-part is technically\n * case-sensitive (though most providers ignore case). Callers should\n * normalize emails (e.g., toLowerCase) before API calls and storage.\n *\n * @param email - The email address to validate\n * @returns true if the email format is valid\n */\nexport function validateEmail(email: string): boolean {\n // Check basic constraints\n if (!email || typeof email !== 'string') {\n return false;\n }\n\n if (email.length > 254) {\n return false;\n }\n\n if (email.includes(' ')) {\n return false;\n }\n\n const parts = email.split('@');\n if (parts.length !== 2) {\n return false;\n }\n\n const [local, domain] = parts;\n if (!local || local.length > 64) {\n return false;\n }\n\n if (local.startsWith('.') || local.endsWith('.')) {\n return false;\n }\n\n if (!domain || domain.length > 253) {\n return false;\n }\n\n if (!domain.includes('.')) {\n return false;\n }\n\n if (\n domain.startsWith('.') ||\n domain.endsWith('.') ||\n domain.startsWith('-') ||\n domain.endsWith('-')\n ) {\n return false;\n }\n\n for (const label of domain.split('.')) {\n if (label.startsWith('-') || label.endsWith('-')) {\n return false;\n }\n }\n\n const tld = domain.split('.').pop();\n if (!tld || tld.length < 2) {\n return false;\n }\n\n if (!/^[a-zA-Z]+$/.test(tld)) {\n return false;\n }\n\n if (TYPO_TLDS.has(tld.toLowerCase())) {\n return false;\n }\n\n if (!/^[a-zA-Z0-9.-]+$/.test(domain)) {\n return false;\n }\n\n if (!/^[a-zA-Z0-9._\\-+!]+$/.test(local)) {\n return false;\n }\n\n return true;\n}\n\n/**\n * Valid Base58 characters (excludes 0, O, I, l to avoid ambiguity)\n */\nconst BASE58_ALPHABET = /^[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]+$/;\n\n/**\n * Validate Solana public key format.\n *\n * A valid Solana public key:\n * - Is 43-44 characters long (base58 encoding of 32 bytes)\n * - Contains only valid base58 characters\n *\n * @param publicKey - The public key string to validate\n * @returns true if the public key format is valid\n *\n * @example\n * ```ts\n * validateSolanaPublicKey('DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263') // true\n * validateSolanaPublicKey('invalid') // false\n * ```\n */\nexport function validateSolanaPublicKey(publicKey: string): boolean {\n // Check length (base58 encoding of 32 bytes is 43-44 chars)\n if (publicKey.length < 43 || publicKey.length > 44) {\n return false;\n }\n\n // Check for valid base58 characters only\n return BASE58_ALPHABET.test(publicKey);\n}\n"],"names":["SPECIAL_CHARS_PATTERN","validatePassword","password","errors","hasLength","hasUppercase","hasLowercase","hasNumber","hasSpecial","criteriaMetCount","strength","TYPO_TLDS","validateEmail","email","parts","local","domain","label","tld","BASE58_ALPHABET","validateSolanaPublicKey","publicKey"],"mappings":"AAUA,MAAMA,IAAwB;AAavB,SAASC,EAAiBC,GAAsC;AACrE,QAAMC,IAAuC,CAAA,GAGvCC,IAAYF,EAAS,UAAU,IAC/BG,IAAe,QAAQ,KAAKH,CAAQ,GACpCI,IAAe,QAAQ,KAAKJ,CAAQ,GACpCK,IAAY,KAAK,KAAKL,CAAQ,GAE9BM,IAAaR,EAAsB,KAAKE,CAAQ;AAGtD,MAAIO,IAAmB;AAGvB,EAAIL,IACFK,MAEAN,EAAO,SAAS,0BAGdE,IACFI,MAEAN,EAAO,YAAY,+BAGjBG,IACFG,MAEAN,EAAO,YAAY,+BAGjBI,IACFE,MAEAN,EAAO,SAAS,qBAGdK,IACFC,MAEAN,EAAO,UAAU;AAInB,MAAIO;AACJ,SAAID,KAAoB,IACtBC,IAAW,SACFD,MAAqB,IAC9BC,IAAW,SACFD,MAAqB,IAC9BC,IAAW,SAEXA,IAAW,UAGN;AAAA,IACL,SAAS,OAAO,KAAKP,CAAM,EAAE,WAAW;AAAA,IACxC,QAAAA;AAAA,IACA,UAAAO;AAAA,EAAA;AAEJ;AAEA,MAAMC,wBAAgB,IAAI;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAmBM,SAASC,EAAcC,GAAwB;AAUpD,MARI,CAACA,KAAS,OAAOA,KAAU,YAI3BA,EAAM,SAAS,OAIfA,EAAM,SAAS,GAAG;AACpB,WAAO;AAGT,QAAMC,IAAQD,EAAM,MAAM,GAAG;AAC7B,MAAIC,EAAM,WAAW;AACnB,WAAO;AAGT,QAAM,CAACC,GAAOC,CAAM,IAAIF;AAiBxB,MAhBI,CAACC,KAASA,EAAM,SAAS,MAIzBA,EAAM,WAAW,GAAG,KAAKA,EAAM,SAAS,GAAG,KAI3C,CAACC,KAAUA,EAAO,SAAS,OAI3B,CAACA,EAAO,SAAS,GAAG,KAKtBA,EAAO,WAAW,GAAG,KACrBA,EAAO,SAAS,GAAG,KACnBA,EAAO,WAAW,GAAG,KACrBA,EAAO,SAAS,GAAG;AAEnB,WAAO;AAGT,aAAWC,KAASD,EAAO,MAAM,GAAG;AAClC,QAAIC,EAAM,WAAW,GAAG,KAAKA,EAAM,SAAS,GAAG;AAC7C,aAAO;AAIX,QAAMC,IAAMF,EAAO,MAAM,GAAG,EAAE,IAAA;AAiB9B,SAhBI,GAACE,KAAOA,EAAI,SAAS,KAIrB,CAAC,cAAc,KAAKA,CAAG,KAIvBP,EAAU,IAAIO,EAAI,YAAA,CAAa,KAI/B,CAAC,mBAAmB,KAAKF,CAAM,KAI/B,CAAC,uBAAuB,KAAKD,CAAK;AAKxC;AAKA,MAAMI,IAAkB;AAkBjB,SAASC,EAAwBC,GAA4B;AAElE,SAAIA,EAAU,SAAS,MAAMA,EAAU,SAAS,KACvC,KAIFF,EAAgB,KAAKE,CAAS;AACvC;"}
package/package.json ADDED
@@ -0,0 +1,109 @@
1
+ {
2
+ "name": "@cedros/login-react",
3
+ "version": "0.0.1",
4
+ "description": "React component library for authentication with email/password, Google OAuth, and Solana wallet sign-in",
5
+ "type": "module",
6
+ "main": "./dist/index.cjs",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "import": {
12
+ "types": "./dist/index.d.ts",
13
+ "default": "./dist/index.js"
14
+ },
15
+ "require": {
16
+ "types": "./dist/index.d.ts",
17
+ "default": "./dist/index.cjs"
18
+ }
19
+ },
20
+ "./email-only": {
21
+ "import": {
22
+ "types": "./dist/email-only.d.ts",
23
+ "default": "./dist/email-only.js"
24
+ },
25
+ "require": {
26
+ "types": "./dist/email-only.d.ts",
27
+ "default": "./dist/email-only.cjs"
28
+ }
29
+ },
30
+ "./google-only": {
31
+ "import": {
32
+ "types": "./dist/google-only.d.ts",
33
+ "default": "./dist/google-only.js"
34
+ },
35
+ "require": {
36
+ "types": "./dist/google-only.d.ts",
37
+ "default": "./dist/google-only.cjs"
38
+ }
39
+ },
40
+ "./solana-only": {
41
+ "import": {
42
+ "types": "./dist/solana-only.d.ts",
43
+ "default": "./dist/solana-only.js"
44
+ },
45
+ "require": {
46
+ "types": "./dist/solana-only.d.ts",
47
+ "default": "./dist/solana-only.cjs"
48
+ }
49
+ },
50
+ "./style.css": "./dist/login-react.css"
51
+ },
52
+ "files": [
53
+ "dist"
54
+ ],
55
+ "sideEffects": [
56
+ "**/*.css"
57
+ ],
58
+ "peerDependencies": {
59
+ "react": "^18.0.0 || ^19.0.0",
60
+ "react-dom": "^18.0.0 || ^19.0.0"
61
+ },
62
+ "peerDependenciesMeta": {
63
+ "@solana/wallet-adapter-base": {
64
+ "optional": true
65
+ },
66
+ "@solana/wallet-adapter-react": {
67
+ "optional": true
68
+ },
69
+ "@solana/wallet-adapter-react-ui": {
70
+ "optional": true
71
+ },
72
+ "@solana/wallet-adapter-wallets": {
73
+ "optional": true
74
+ },
75
+ "@solana/web3.js": {
76
+ "optional": true
77
+ }
78
+ },
79
+ "keywords": [
80
+ "react",
81
+ "authentication",
82
+ "login",
83
+ "google-oauth",
84
+ "solana",
85
+ "wallet",
86
+ "cedros"
87
+ ],
88
+ "license": "MIT",
89
+ "engines": {
90
+ "node": ">=18.0.0"
91
+ },
92
+ "repository": {
93
+ "type": "git",
94
+ "url": "https://github.com/conorholds/cedros-login.git",
95
+ "directory": "ui"
96
+ },
97
+ "bugs": {
98
+ "url": "https://github.com/conorholds/cedros-login/issues"
99
+ },
100
+ "homepage": "https://github.com/conorholds/cedros-login#readme",
101
+ "dependencies": {
102
+ "@noble/curves": "^2.0.1",
103
+ "@noble/hashes": "^1.7.2",
104
+ "@scure/bip39": "^1.6.0",
105
+ "hash-wasm": "^4.12.0",
106
+ "qrcode": "^1.5.4",
107
+ "secrets.js-grempe": "^2.0.0"
108
+ }
109
+ }