@insforge/react 1.1.5 → 1.1.6-test.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/atoms.cjs +1 -0
- package/dist/atoms.cjs.map +1 -1
- package/dist/atoms.js +1 -0
- package/dist/atoms.js.map +1 -1
- package/dist/components.cjs +95 -4
- package/dist/components.cjs.map +1 -1
- package/dist/components.js +95 -4
- package/dist/components.js.map +1 -1
- package/dist/forms.cjs +1 -0
- package/dist/forms.cjs.map +1 -1
- package/dist/forms.js +1 -0
- package/dist/forms.js.map +1 -1
- package/dist/hooks.cjs +1 -0
- package/dist/hooks.cjs.map +1 -1
- package/dist/hooks.js +1 -0
- package/dist/hooks.js.map +1 -1
- package/dist/index.cjs +119 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +118 -6
- package/dist/index.js.map +1 -1
- package/dist/lib.cjs +30 -0
- package/dist/lib.cjs.map +1 -1
- package/dist/lib.d.cts +39 -1
- package/dist/lib.d.ts +39 -1
- package/dist/lib.js +29 -1
- package/dist/lib.js.map +1 -1
- package/package.json +2 -2
package/dist/lib.cjs
CHANGED
|
@@ -97,9 +97,39 @@ function resolveAuthUrl(targetPath, searchParams) {
|
|
|
97
97
|
return `${resolvedPath}?${searchParams.toString()}`;
|
|
98
98
|
}
|
|
99
99
|
|
|
100
|
+
// src/lib/hosted-auth.ts
|
|
101
|
+
function isHostedAuthEnvironment() {
|
|
102
|
+
if (typeof window === "undefined") {
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
const { hostname, port, protocol } = window.location;
|
|
106
|
+
if (hostname === "localhost" && port === "7130") {
|
|
107
|
+
return true;
|
|
108
|
+
}
|
|
109
|
+
if (protocol === "https:" && hostname.endsWith(".insforge.app")) {
|
|
110
|
+
return true;
|
|
111
|
+
}
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
function buildLegacyAuthUrl(redirectUrl, session) {
|
|
115
|
+
const url = new URL(redirectUrl);
|
|
116
|
+
url.searchParams.set("access_token", session.accessToken);
|
|
117
|
+
url.searchParams.set("user_id", session.userId);
|
|
118
|
+
url.searchParams.set("email", session.email);
|
|
119
|
+
if (session.name) {
|
|
120
|
+
url.searchParams.set("name", session.name);
|
|
121
|
+
}
|
|
122
|
+
if (session.csrfToken) {
|
|
123
|
+
url.searchParams.set("csrf_token", session.csrfToken);
|
|
124
|
+
}
|
|
125
|
+
return url.toString();
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
exports.buildLegacyAuthUrl = buildLegacyAuthUrl;
|
|
100
129
|
exports.checkPasswordStrength = checkPasswordStrength;
|
|
101
130
|
exports.createPasswordSchema = createPasswordSchema;
|
|
102
131
|
exports.emailSchema = emailSchema;
|
|
132
|
+
exports.isHostedAuthEnvironment = isHostedAuthEnvironment;
|
|
103
133
|
exports.passwordSchema = passwordSchema;
|
|
104
134
|
exports.resolveAuthPath = resolveAuthPath;
|
|
105
135
|
exports.resolveAuthUrl = resolveAuthUrl;
|
package/dist/lib.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lib/validation.ts","../src/lib/path-utils.ts"],"names":["z"],"mappings":"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","file":"lib.cjs","sourcesContent":["import { z } from 'zod';\n\n/**\n * Email validation schema\n */\nexport const emailSchema = z.string().min(1, 'Email is required').email('Invalid email address');\n\n/**\n * Password validation schema with configurable requirements\n */\nexport function createPasswordSchema(options?: {\n minLength?: number;\n requireUppercase?: boolean;\n requireLowercase?: boolean;\n requireNumber?: boolean;\n requireSpecialChar?: boolean;\n}) {\n const {\n minLength = 6,\n requireUppercase = false,\n requireLowercase = false,\n requireNumber = false,\n requireSpecialChar = false,\n } = options || {};\n\n let schema = z.string().min(minLength, `Password must be at least ${minLength} characters`);\n\n if (requireUppercase) {\n schema = schema.regex(/[A-Z]/, 'Password must contain at least one uppercase letter');\n }\n\n if (requireLowercase) {\n schema = schema.regex(/[a-z]/, 'Password must contain at least one lowercase letter');\n }\n\n if (requireNumber) {\n schema = schema.regex(/\\d/, 'Password must contain at least one number');\n }\n\n if (requireSpecialChar) {\n schema = schema.regex(\n /[!@#$%^&*()_+\\-=[\\]{};':\"\\\\|,.<>/?]/,\n 'Password must contain at least one special character'\n );\n }\n\n return schema;\n}\n\n/**\n * Default password schema (minimum 6 characters)\n */\nexport const passwordSchema = createPasswordSchema();\n\n/**\n * Validate email format\n */\nexport function validateEmail(email: string): { valid: boolean; error?: string } {\n const result = emailSchema.safeParse(email);\n if (result.success) {\n return { valid: true };\n }\n return { valid: false, error: result.error.message };\n}\n\n/**\n * Validate password format\n */\nexport function validatePassword(\n password: string,\n options?: Parameters<typeof createPasswordSchema>[0]\n): { valid: boolean; error?: string } {\n const schema = createPasswordSchema(options);\n const result = schema.safeParse(password);\n if (result.success) {\n return { valid: true };\n }\n return { valid: false, error: result.error.message };\n}\n\n/**\n * Validate password strength based on multiple criteria\n */\nexport function checkPasswordStrength(password: string): {\n score: number;\n feedback: string[];\n} {\n const feedback: string[] = [];\n let score = 0;\n\n if (password.length >= 8) {\n score += 1;\n } else {\n feedback.push('Use at least 8 characters');\n }\n\n if (password.length >= 12) {\n score += 1;\n }\n\n if (/[a-z]/.test(password) && /[A-Z]/.test(password)) {\n score += 1;\n } else {\n feedback.push('Use both uppercase and lowercase letters');\n }\n\n if (/\\d/.test(password)) {\n score += 1;\n } else {\n feedback.push('Include at least one number');\n }\n\n if (/[!@#$%^&*()_+\\-=[\\]{};':\"\\\\|,.<>/?]/.test(password)) {\n score += 1;\n } else {\n feedback.push('Include at least one special character');\n }\n\n return { score, feedback };\n}\n","/**\n * Path utilities for handling navigation in auth flows.\n * Ensures proper path resolution when auth pages are served under a base path (e.g., /auth/)\n */\n\n/**\n * Resolves an auth route path relative to the current location.\n * If the current path is under /auth/, it will preserve that prefix.\n * Otherwise, it returns the path as-is.\n *\n * @param targetPath - The target auth path (e.g., '/sign-in', '/sign-up')\n * @returns The resolved path with proper base path handling\n *\n * @example\n * // Current URL: http://localhost:5174/auth/sign-in\n * resolveAuthPath('/sign-up') // Returns '/auth/sign-up'\n *\n * @example\n * // Current URL: http://localhost:5174/sign-in\n * resolveAuthPath('/sign-up') // Returns '/sign-up'\n */\nexport function resolveAuthPath(targetPath: string): string {\n if (typeof window === 'undefined') {\n return targetPath;\n }\n\n const currentPath = window.location.pathname;\n\n // Check if we're currently under /auth/ base path\n if (currentPath.startsWith('/auth/')) {\n // If target already has /auth/ prefix, return as-is\n if (targetPath.startsWith('/auth/')) {\n return targetPath;\n }\n // Add /auth/ prefix to the target path\n return `/auth${targetPath}`;\n }\n\n // Not under /auth/, return target path as-is\n return targetPath;\n}\n\n/**\n * Resolves an auth route URL with search params preserved.\n * Similar to resolveAuthPath but returns a full URL string with query parameters.\n *\n * @param targetPath - The target auth path (e.g., '/sign-in', '/sign-up')\n * @param searchParams - Optional URLSearchParams to append\n * @returns The resolved URL as a string\n *\n * @example\n * // Current URL: http://localhost:5174/auth/sign-in?redirect=...\n * resolveAuthUrl('/sign-up', searchParams) // Returns '/auth/sign-up?redirect=...'\n */\nexport function resolveAuthUrl(targetPath: string, searchParams?: URLSearchParams): string {\n const resolvedPath = resolveAuthPath(targetPath);\n\n if (!searchParams || searchParams.toString() === '') {\n return resolvedPath;\n }\n\n return `${resolvedPath}?${searchParams.toString()}`;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/lib/validation.ts","../src/lib/path-utils.ts","../src/lib/hosted-auth.ts"],"names":["z"],"mappings":"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","file":"lib.cjs","sourcesContent":["import { z } from 'zod';\n\n/**\n * Email validation schema\n */\nexport const emailSchema = z.string().min(1, 'Email is required').email('Invalid email address');\n\n/**\n * Password validation schema with configurable requirements\n */\nexport function createPasswordSchema(options?: {\n minLength?: number;\n requireUppercase?: boolean;\n requireLowercase?: boolean;\n requireNumber?: boolean;\n requireSpecialChar?: boolean;\n}) {\n const {\n minLength = 6,\n requireUppercase = false,\n requireLowercase = false,\n requireNumber = false,\n requireSpecialChar = false,\n } = options || {};\n\n let schema = z.string().min(minLength, `Password must be at least ${minLength} characters`);\n\n if (requireUppercase) {\n schema = schema.regex(/[A-Z]/, 'Password must contain at least one uppercase letter');\n }\n\n if (requireLowercase) {\n schema = schema.regex(/[a-z]/, 'Password must contain at least one lowercase letter');\n }\n\n if (requireNumber) {\n schema = schema.regex(/\\d/, 'Password must contain at least one number');\n }\n\n if (requireSpecialChar) {\n schema = schema.regex(\n /[!@#$%^&*()_+\\-=[\\]{};':\"\\\\|,.<>/?]/,\n 'Password must contain at least one special character'\n );\n }\n\n return schema;\n}\n\n/**\n * Default password schema (minimum 6 characters)\n */\nexport const passwordSchema = createPasswordSchema();\n\n/**\n * Validate email format\n */\nexport function validateEmail(email: string): { valid: boolean; error?: string } {\n const result = emailSchema.safeParse(email);\n if (result.success) {\n return { valid: true };\n }\n return { valid: false, error: result.error.message };\n}\n\n/**\n * Validate password format\n */\nexport function validatePassword(\n password: string,\n options?: Parameters<typeof createPasswordSchema>[0]\n): { valid: boolean; error?: string } {\n const schema = createPasswordSchema(options);\n const result = schema.safeParse(password);\n if (result.success) {\n return { valid: true };\n }\n return { valid: false, error: result.error.message };\n}\n\n/**\n * Validate password strength based on multiple criteria\n */\nexport function checkPasswordStrength(password: string): {\n score: number;\n feedback: string[];\n} {\n const feedback: string[] = [];\n let score = 0;\n\n if (password.length >= 8) {\n score += 1;\n } else {\n feedback.push('Use at least 8 characters');\n }\n\n if (password.length >= 12) {\n score += 1;\n }\n\n if (/[a-z]/.test(password) && /[A-Z]/.test(password)) {\n score += 1;\n } else {\n feedback.push('Use both uppercase and lowercase letters');\n }\n\n if (/\\d/.test(password)) {\n score += 1;\n } else {\n feedback.push('Include at least one number');\n }\n\n if (/[!@#$%^&*()_+\\-=[\\]{};':\"\\\\|,.<>/?]/.test(password)) {\n score += 1;\n } else {\n feedback.push('Include at least one special character');\n }\n\n return { score, feedback };\n}\n","/**\n * Path utilities for handling navigation in auth flows.\n * Ensures proper path resolution when auth pages are served under a base path (e.g., /auth/)\n */\n\n/**\n * Resolves an auth route path relative to the current location.\n * If the current path is under /auth/, it will preserve that prefix.\n * Otherwise, it returns the path as-is.\n *\n * @param targetPath - The target auth path (e.g., '/sign-in', '/sign-up')\n * @returns The resolved path with proper base path handling\n *\n * @example\n * // Current URL: http://localhost:5174/auth/sign-in\n * resolveAuthPath('/sign-up') // Returns '/auth/sign-up'\n *\n * @example\n * // Current URL: http://localhost:5174/sign-in\n * resolveAuthPath('/sign-up') // Returns '/sign-up'\n */\nexport function resolveAuthPath(targetPath: string): string {\n if (typeof window === 'undefined') {\n return targetPath;\n }\n\n const currentPath = window.location.pathname;\n\n // Check if we're currently under /auth/ base path\n if (currentPath.startsWith('/auth/')) {\n // If target already has /auth/ prefix, return as-is\n if (targetPath.startsWith('/auth/')) {\n return targetPath;\n }\n // Add /auth/ prefix to the target path\n return `/auth${targetPath}`;\n }\n\n // Not under /auth/, return target path as-is\n return targetPath;\n}\n\n/**\n * Resolves an auth route URL with search params preserved.\n * Similar to resolveAuthPath but returns a full URL string with query parameters.\n *\n * @param targetPath - The target auth path (e.g., '/sign-in', '/sign-up')\n * @param searchParams - Optional URLSearchParams to append\n * @returns The resolved URL as a string\n *\n * @example\n * // Current URL: http://localhost:5174/auth/sign-in?redirect=...\n * resolveAuthUrl('/sign-up', searchParams) // Returns '/auth/sign-up?redirect=...'\n */\nexport function resolveAuthUrl(targetPath: string, searchParams?: URLSearchParams): string {\n const resolvedPath = resolveAuthPath(targetPath);\n\n if (!searchParams || searchParams.toString() === '') {\n return resolvedPath;\n }\n\n return `${resolvedPath}?${searchParams.toString()}`;\n}\n","/**\n * Hosted Auth Helpers\n *\n * Utilities for detecting hosted auth environment and building legacy auth URLs\n * for cross-domain authentication flows.\n */\n\n/**\n * Check if current environment is a hosted auth environment\n *\n * Returns true for:\n * - localhost with port 7130 (hosted auth app dev)\n * - https://*.insforge.app (hosted auth app production)\n *\n * @returns true if running in hosted auth environment\n */\nexport function isHostedAuthEnvironment(): boolean {\n if (typeof window === 'undefined') {\n return false;\n }\n\n const { hostname, port, protocol } = window.location;\n\n // Local development\n if (hostname === 'localhost' && port === '7130') {\n return true;\n }\n\n // Production hosted auth\n if (protocol === 'https:' && hostname.endsWith('.insforge.app')) {\n return true;\n }\n\n return false;\n}\n\n/**\n * Session data for building legacy auth URL\n */\nexport interface LegacyAuthSession {\n accessToken: string;\n userId: string;\n email: string;\n name?: string;\n csrfToken?: string;\n}\n\n/**\n * Build a legacy flow redirect URL with auth params in query string\n *\n * This is used to pass authentication credentials back to the user's app\n * after OAuth completes in the hosted auth environment.\n *\n * @param redirectUrl - The URL to redirect to (user's app)\n * @param session - The session data to include in the URL\n * @returns The complete URL with auth params\n */\nexport function buildLegacyAuthUrl(\n redirectUrl: string,\n session: LegacyAuthSession\n): string {\n const url = new URL(redirectUrl);\n url.searchParams.set('access_token', session.accessToken);\n url.searchParams.set('user_id', session.userId);\n url.searchParams.set('email', session.email);\n\n if (session.name) {\n url.searchParams.set('name', session.name);\n }\n\n if (session.csrfToken) {\n url.searchParams.set('csrf_token', session.csrfToken);\n }\n\n return url.toString();\n}\n"]}
|
package/dist/lib.d.cts
CHANGED
|
@@ -75,4 +75,42 @@ declare function resolveAuthPath(targetPath: string): string;
|
|
|
75
75
|
*/
|
|
76
76
|
declare function resolveAuthUrl(targetPath: string, searchParams?: URLSearchParams): string;
|
|
77
77
|
|
|
78
|
-
|
|
78
|
+
/**
|
|
79
|
+
* Hosted Auth Helpers
|
|
80
|
+
*
|
|
81
|
+
* Utilities for detecting hosted auth environment and building legacy auth URLs
|
|
82
|
+
* for cross-domain authentication flows.
|
|
83
|
+
*/
|
|
84
|
+
/**
|
|
85
|
+
* Check if current environment is a hosted auth environment
|
|
86
|
+
*
|
|
87
|
+
* Returns true for:
|
|
88
|
+
* - localhost with port 7130 (hosted auth app dev)
|
|
89
|
+
* - https://*.insforge.app (hosted auth app production)
|
|
90
|
+
*
|
|
91
|
+
* @returns true if running in hosted auth environment
|
|
92
|
+
*/
|
|
93
|
+
declare function isHostedAuthEnvironment(): boolean;
|
|
94
|
+
/**
|
|
95
|
+
* Session data for building legacy auth URL
|
|
96
|
+
*/
|
|
97
|
+
interface LegacyAuthSession {
|
|
98
|
+
accessToken: string;
|
|
99
|
+
userId: string;
|
|
100
|
+
email: string;
|
|
101
|
+
name?: string;
|
|
102
|
+
csrfToken?: string;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Build a legacy flow redirect URL with auth params in query string
|
|
106
|
+
*
|
|
107
|
+
* This is used to pass authentication credentials back to the user's app
|
|
108
|
+
* after OAuth completes in the hosted auth environment.
|
|
109
|
+
*
|
|
110
|
+
* @param redirectUrl - The URL to redirect to (user's app)
|
|
111
|
+
* @param session - The session data to include in the URL
|
|
112
|
+
* @returns The complete URL with auth params
|
|
113
|
+
*/
|
|
114
|
+
declare function buildLegacyAuthUrl(redirectUrl: string, session: LegacyAuthSession): string;
|
|
115
|
+
|
|
116
|
+
export { type LegacyAuthSession, buildLegacyAuthUrl, checkPasswordStrength, createPasswordSchema, emailSchema, isHostedAuthEnvironment, passwordSchema, resolveAuthPath, resolveAuthUrl, validateEmail, validatePassword };
|
package/dist/lib.d.ts
CHANGED
|
@@ -75,4 +75,42 @@ declare function resolveAuthPath(targetPath: string): string;
|
|
|
75
75
|
*/
|
|
76
76
|
declare function resolveAuthUrl(targetPath: string, searchParams?: URLSearchParams): string;
|
|
77
77
|
|
|
78
|
-
|
|
78
|
+
/**
|
|
79
|
+
* Hosted Auth Helpers
|
|
80
|
+
*
|
|
81
|
+
* Utilities for detecting hosted auth environment and building legacy auth URLs
|
|
82
|
+
* for cross-domain authentication flows.
|
|
83
|
+
*/
|
|
84
|
+
/**
|
|
85
|
+
* Check if current environment is a hosted auth environment
|
|
86
|
+
*
|
|
87
|
+
* Returns true for:
|
|
88
|
+
* - localhost with port 7130 (hosted auth app dev)
|
|
89
|
+
* - https://*.insforge.app (hosted auth app production)
|
|
90
|
+
*
|
|
91
|
+
* @returns true if running in hosted auth environment
|
|
92
|
+
*/
|
|
93
|
+
declare function isHostedAuthEnvironment(): boolean;
|
|
94
|
+
/**
|
|
95
|
+
* Session data for building legacy auth URL
|
|
96
|
+
*/
|
|
97
|
+
interface LegacyAuthSession {
|
|
98
|
+
accessToken: string;
|
|
99
|
+
userId: string;
|
|
100
|
+
email: string;
|
|
101
|
+
name?: string;
|
|
102
|
+
csrfToken?: string;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Build a legacy flow redirect URL with auth params in query string
|
|
106
|
+
*
|
|
107
|
+
* This is used to pass authentication credentials back to the user's app
|
|
108
|
+
* after OAuth completes in the hosted auth environment.
|
|
109
|
+
*
|
|
110
|
+
* @param redirectUrl - The URL to redirect to (user's app)
|
|
111
|
+
* @param session - The session data to include in the URL
|
|
112
|
+
* @returns The complete URL with auth params
|
|
113
|
+
*/
|
|
114
|
+
declare function buildLegacyAuthUrl(redirectUrl: string, session: LegacyAuthSession): string;
|
|
115
|
+
|
|
116
|
+
export { type LegacyAuthSession, buildLegacyAuthUrl, checkPasswordStrength, createPasswordSchema, emailSchema, isHostedAuthEnvironment, passwordSchema, resolveAuthPath, resolveAuthUrl, validateEmail, validatePassword };
|
package/dist/lib.js
CHANGED
|
@@ -95,6 +95,34 @@ function resolveAuthUrl(targetPath, searchParams) {
|
|
|
95
95
|
return `${resolvedPath}?${searchParams.toString()}`;
|
|
96
96
|
}
|
|
97
97
|
|
|
98
|
-
|
|
98
|
+
// src/lib/hosted-auth.ts
|
|
99
|
+
function isHostedAuthEnvironment() {
|
|
100
|
+
if (typeof window === "undefined") {
|
|
101
|
+
return false;
|
|
102
|
+
}
|
|
103
|
+
const { hostname, port, protocol } = window.location;
|
|
104
|
+
if (hostname === "localhost" && port === "7130") {
|
|
105
|
+
return true;
|
|
106
|
+
}
|
|
107
|
+
if (protocol === "https:" && hostname.endsWith(".insforge.app")) {
|
|
108
|
+
return true;
|
|
109
|
+
}
|
|
110
|
+
return false;
|
|
111
|
+
}
|
|
112
|
+
function buildLegacyAuthUrl(redirectUrl, session) {
|
|
113
|
+
const url = new URL(redirectUrl);
|
|
114
|
+
url.searchParams.set("access_token", session.accessToken);
|
|
115
|
+
url.searchParams.set("user_id", session.userId);
|
|
116
|
+
url.searchParams.set("email", session.email);
|
|
117
|
+
if (session.name) {
|
|
118
|
+
url.searchParams.set("name", session.name);
|
|
119
|
+
}
|
|
120
|
+
if (session.csrfToken) {
|
|
121
|
+
url.searchParams.set("csrf_token", session.csrfToken);
|
|
122
|
+
}
|
|
123
|
+
return url.toString();
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export { buildLegacyAuthUrl, checkPasswordStrength, createPasswordSchema, emailSchema, isHostedAuthEnvironment, passwordSchema, resolveAuthPath, resolveAuthUrl, validateEmail, validatePassword };
|
|
99
127
|
//# sourceMappingURL=lib.js.map
|
|
100
128
|
//# sourceMappingURL=lib.js.map
|
package/dist/lib.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lib/validation.ts","../src/lib/path-utils.ts"],"names":[],"mappings":";;;AAKO,IAAM,WAAA,GAAc,EAAE,MAAA,EAAO,CAAE,IAAI,CAAA,EAAG,mBAAmB,CAAA,CAAE,KAAA,CAAM,uBAAuB;AAKxF,SAAS,qBAAqB,OAAA,EAMlC;AACD,EAAA,MAAM;AAAA,IACJ,SAAA,GAAY,CAAA;AAAA,IACZ,gBAAA,GAAmB,KAAA;AAAA,IACnB,gBAAA,GAAmB,KAAA;AAAA,IACnB,aAAA,GAAgB,KAAA;AAAA,IAChB,kBAAA,GAAqB;AAAA,GACvB,GAAI,WAAW,EAAC;AAEhB,EAAA,IAAI,MAAA,GAAS,EAAE,MAAA,EAAO,CAAE,IAAI,SAAA,EAAW,CAAA,0BAAA,EAA6B,SAAS,CAAA,WAAA,CAAa,CAAA;AAE1F,EAAA,IAAI,gBAAA,EAAkB;AACpB,IAAA,MAAA,GAAS,MAAA,CAAO,KAAA,CAAM,OAAA,EAAS,qDAAqD,CAAA;AAAA,EACtF;AAEA,EAAA,IAAI,gBAAA,EAAkB;AACpB,IAAA,MAAA,GAAS,MAAA,CAAO,KAAA,CAAM,OAAA,EAAS,qDAAqD,CAAA;AAAA,EACtF;AAEA,EAAA,IAAI,aAAA,EAAe;AACjB,IAAA,MAAA,GAAS,MAAA,CAAO,KAAA,CAAM,IAAA,EAAM,2CAA2C,CAAA;AAAA,EACzE;AAEA,EAAA,IAAI,kBAAA,EAAoB;AACtB,IAAA,MAAA,GAAS,MAAA,CAAO,KAAA;AAAA,MACd,qCAAA;AAAA,MACA;AAAA,KACF;AAAA,EACF;AAEA,EAAA,OAAO,MAAA;AACT;AAKO,IAAM,iBAAiB,oBAAA;AAKvB,SAAS,cAAc,KAAA,EAAmD;AAC/E,EAAA,MAAM,MAAA,GAAS,WAAA,CAAY,SAAA,CAAU,KAAK,CAAA;AAC1C,EAAA,IAAI,OAAO,OAAA,EAAS;AAClB,IAAA,OAAO,EAAE,OAAO,IAAA,EAAK;AAAA,EACvB;AACA,EAAA,OAAO,EAAE,KAAA,EAAO,KAAA,EAAO,KAAA,EAAO,MAAA,CAAO,MAAM,OAAA,EAAQ;AACrD;AAKO,SAAS,gBAAA,CACd,UACA,OAAA,EACoC;AACpC,EAAA,MAAM,MAAA,GAAS,qBAAqB,OAAO,CAAA;AAC3C,EAAA,MAAM,MAAA,GAAS,MAAA,CAAO,SAAA,CAAU,QAAQ,CAAA;AACxC,EAAA,IAAI,OAAO,OAAA,EAAS;AAClB,IAAA,OAAO,EAAE,OAAO,IAAA,EAAK;AAAA,EACvB;AACA,EAAA,OAAO,EAAE,KAAA,EAAO,KAAA,EAAO,KAAA,EAAO,MAAA,CAAO,MAAM,OAAA,EAAQ;AACrD;AAKO,SAAS,sBAAsB,QAAA,EAGpC;AACA,EAAA,MAAM,WAAqB,EAAC;AAC5B,EAAA,IAAI,KAAA,GAAQ,CAAA;AAEZ,EAAA,IAAI,QAAA,CAAS,UAAU,CAAA,EAAG;AACxB,IAAA,KAAA,IAAS,CAAA;AAAA,EACX,CAAA,MAAO;AACL,IAAA,QAAA,CAAS,KAAK,2BAA2B,CAAA;AAAA,EAC3C;AAEA,EAAA,IAAI,QAAA,CAAS,UAAU,EAAA,EAAI;AACzB,IAAA,KAAA,IAAS,CAAA;AAAA,EACX;AAEA,EAAA,IAAI,QAAQ,IAAA,CAAK,QAAQ,KAAK,OAAA,CAAQ,IAAA,CAAK,QAAQ,CAAA,EAAG;AACpD,IAAA,KAAA,IAAS,CAAA;AAAA,EACX,CAAA,MAAO;AACL,IAAA,QAAA,CAAS,KAAK,0CAA0C,CAAA;AAAA,EAC1D;AAEA,EAAA,IAAI,IAAA,CAAK,IAAA,CAAK,QAAQ,CAAA,EAAG;AACvB,IAAA,KAAA,IAAS,CAAA;AAAA,EACX,CAAA,MAAO;AACL,IAAA,QAAA,CAAS,KAAK,6BAA6B,CAAA;AAAA,EAC7C;AAEA,EAAA,IAAI,qCAAA,CAAsC,IAAA,CAAK,QAAQ,CAAA,EAAG;AACxD,IAAA,KAAA,IAAS,CAAA;AAAA,EACX,CAAA,MAAO;AACL,IAAA,QAAA,CAAS,KAAK,wCAAwC,CAAA;AAAA,EACxD;AAEA,EAAA,OAAO,EAAE,OAAO,QAAA,EAAS;AAC3B;;;AClGO,SAAS,gBAAgB,UAAA,EAA4B;AAC1D,EAAA,IAAI,OAAO,WAAW,WAAA,EAAa;AACjC,IAAA,OAAO,UAAA;AAAA,EACT;AAEA,EAAA,MAAM,WAAA,GAAc,OAAO,QAAA,CAAS,QAAA;AAGpC,EAAA,IAAI,WAAA,CAAY,UAAA,CAAW,QAAQ,CAAA,EAAG;AAEpC,IAAA,IAAI,UAAA,CAAW,UAAA,CAAW,QAAQ,CAAA,EAAG;AACnC,MAAA,OAAO,UAAA;AAAA,IACT;AAEA,IAAA,OAAO,QAAQ,UAAU,CAAA,CAAA;AAAA,EAC3B;AAGA,EAAA,OAAO,UAAA;AACT;AAcO,SAAS,cAAA,CAAe,YAAoB,YAAA,EAAwC;AACzF,EAAA,MAAM,YAAA,GAAe,gBAAgB,UAAU,CAAA;AAE/C,EAAA,IAAI,CAAC,YAAA,IAAgB,YAAA,CAAa,QAAA,OAAe,EAAA,EAAI;AACnD,IAAA,OAAO,YAAA;AAAA,EACT;AAEA,EAAA,OAAO,CAAA,EAAG,YAAY,CAAA,CAAA,EAAI,YAAA,CAAa,UAAU,CAAA,CAAA;AACnD","file":"lib.js","sourcesContent":["import { z } from 'zod';\n\n/**\n * Email validation schema\n */\nexport const emailSchema = z.string().min(1, 'Email is required').email('Invalid email address');\n\n/**\n * Password validation schema with configurable requirements\n */\nexport function createPasswordSchema(options?: {\n minLength?: number;\n requireUppercase?: boolean;\n requireLowercase?: boolean;\n requireNumber?: boolean;\n requireSpecialChar?: boolean;\n}) {\n const {\n minLength = 6,\n requireUppercase = false,\n requireLowercase = false,\n requireNumber = false,\n requireSpecialChar = false,\n } = options || {};\n\n let schema = z.string().min(minLength, `Password must be at least ${minLength} characters`);\n\n if (requireUppercase) {\n schema = schema.regex(/[A-Z]/, 'Password must contain at least one uppercase letter');\n }\n\n if (requireLowercase) {\n schema = schema.regex(/[a-z]/, 'Password must contain at least one lowercase letter');\n }\n\n if (requireNumber) {\n schema = schema.regex(/\\d/, 'Password must contain at least one number');\n }\n\n if (requireSpecialChar) {\n schema = schema.regex(\n /[!@#$%^&*()_+\\-=[\\]{};':\"\\\\|,.<>/?]/,\n 'Password must contain at least one special character'\n );\n }\n\n return schema;\n}\n\n/**\n * Default password schema (minimum 6 characters)\n */\nexport const passwordSchema = createPasswordSchema();\n\n/**\n * Validate email format\n */\nexport function validateEmail(email: string): { valid: boolean; error?: string } {\n const result = emailSchema.safeParse(email);\n if (result.success) {\n return { valid: true };\n }\n return { valid: false, error: result.error.message };\n}\n\n/**\n * Validate password format\n */\nexport function validatePassword(\n password: string,\n options?: Parameters<typeof createPasswordSchema>[0]\n): { valid: boolean; error?: string } {\n const schema = createPasswordSchema(options);\n const result = schema.safeParse(password);\n if (result.success) {\n return { valid: true };\n }\n return { valid: false, error: result.error.message };\n}\n\n/**\n * Validate password strength based on multiple criteria\n */\nexport function checkPasswordStrength(password: string): {\n score: number;\n feedback: string[];\n} {\n const feedback: string[] = [];\n let score = 0;\n\n if (password.length >= 8) {\n score += 1;\n } else {\n feedback.push('Use at least 8 characters');\n }\n\n if (password.length >= 12) {\n score += 1;\n }\n\n if (/[a-z]/.test(password) && /[A-Z]/.test(password)) {\n score += 1;\n } else {\n feedback.push('Use both uppercase and lowercase letters');\n }\n\n if (/\\d/.test(password)) {\n score += 1;\n } else {\n feedback.push('Include at least one number');\n }\n\n if (/[!@#$%^&*()_+\\-=[\\]{};':\"\\\\|,.<>/?]/.test(password)) {\n score += 1;\n } else {\n feedback.push('Include at least one special character');\n }\n\n return { score, feedback };\n}\n","/**\n * Path utilities for handling navigation in auth flows.\n * Ensures proper path resolution when auth pages are served under a base path (e.g., /auth/)\n */\n\n/**\n * Resolves an auth route path relative to the current location.\n * If the current path is under /auth/, it will preserve that prefix.\n * Otherwise, it returns the path as-is.\n *\n * @param targetPath - The target auth path (e.g., '/sign-in', '/sign-up')\n * @returns The resolved path with proper base path handling\n *\n * @example\n * // Current URL: http://localhost:5174/auth/sign-in\n * resolveAuthPath('/sign-up') // Returns '/auth/sign-up'\n *\n * @example\n * // Current URL: http://localhost:5174/sign-in\n * resolveAuthPath('/sign-up') // Returns '/sign-up'\n */\nexport function resolveAuthPath(targetPath: string): string {\n if (typeof window === 'undefined') {\n return targetPath;\n }\n\n const currentPath = window.location.pathname;\n\n // Check if we're currently under /auth/ base path\n if (currentPath.startsWith('/auth/')) {\n // If target already has /auth/ prefix, return as-is\n if (targetPath.startsWith('/auth/')) {\n return targetPath;\n }\n // Add /auth/ prefix to the target path\n return `/auth${targetPath}`;\n }\n\n // Not under /auth/, return target path as-is\n return targetPath;\n}\n\n/**\n * Resolves an auth route URL with search params preserved.\n * Similar to resolveAuthPath but returns a full URL string with query parameters.\n *\n * @param targetPath - The target auth path (e.g., '/sign-in', '/sign-up')\n * @param searchParams - Optional URLSearchParams to append\n * @returns The resolved URL as a string\n *\n * @example\n * // Current URL: http://localhost:5174/auth/sign-in?redirect=...\n * resolveAuthUrl('/sign-up', searchParams) // Returns '/auth/sign-up?redirect=...'\n */\nexport function resolveAuthUrl(targetPath: string, searchParams?: URLSearchParams): string {\n const resolvedPath = resolveAuthPath(targetPath);\n\n if (!searchParams || searchParams.toString() === '') {\n return resolvedPath;\n }\n\n return `${resolvedPath}?${searchParams.toString()}`;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/lib/validation.ts","../src/lib/path-utils.ts","../src/lib/hosted-auth.ts"],"names":[],"mappings":"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","file":"lib.js","sourcesContent":["import { z } from 'zod';\n\n/**\n * Email validation schema\n */\nexport const emailSchema = z.string().min(1, 'Email is required').email('Invalid email address');\n\n/**\n * Password validation schema with configurable requirements\n */\nexport function createPasswordSchema(options?: {\n minLength?: number;\n requireUppercase?: boolean;\n requireLowercase?: boolean;\n requireNumber?: boolean;\n requireSpecialChar?: boolean;\n}) {\n const {\n minLength = 6,\n requireUppercase = false,\n requireLowercase = false,\n requireNumber = false,\n requireSpecialChar = false,\n } = options || {};\n\n let schema = z.string().min(minLength, `Password must be at least ${minLength} characters`);\n\n if (requireUppercase) {\n schema = schema.regex(/[A-Z]/, 'Password must contain at least one uppercase letter');\n }\n\n if (requireLowercase) {\n schema = schema.regex(/[a-z]/, 'Password must contain at least one lowercase letter');\n }\n\n if (requireNumber) {\n schema = schema.regex(/\\d/, 'Password must contain at least one number');\n }\n\n if (requireSpecialChar) {\n schema = schema.regex(\n /[!@#$%^&*()_+\\-=[\\]{};':\"\\\\|,.<>/?]/,\n 'Password must contain at least one special character'\n );\n }\n\n return schema;\n}\n\n/**\n * Default password schema (minimum 6 characters)\n */\nexport const passwordSchema = createPasswordSchema();\n\n/**\n * Validate email format\n */\nexport function validateEmail(email: string): { valid: boolean; error?: string } {\n const result = emailSchema.safeParse(email);\n if (result.success) {\n return { valid: true };\n }\n return { valid: false, error: result.error.message };\n}\n\n/**\n * Validate password format\n */\nexport function validatePassword(\n password: string,\n options?: Parameters<typeof createPasswordSchema>[0]\n): { valid: boolean; error?: string } {\n const schema = createPasswordSchema(options);\n const result = schema.safeParse(password);\n if (result.success) {\n return { valid: true };\n }\n return { valid: false, error: result.error.message };\n}\n\n/**\n * Validate password strength based on multiple criteria\n */\nexport function checkPasswordStrength(password: string): {\n score: number;\n feedback: string[];\n} {\n const feedback: string[] = [];\n let score = 0;\n\n if (password.length >= 8) {\n score += 1;\n } else {\n feedback.push('Use at least 8 characters');\n }\n\n if (password.length >= 12) {\n score += 1;\n }\n\n if (/[a-z]/.test(password) && /[A-Z]/.test(password)) {\n score += 1;\n } else {\n feedback.push('Use both uppercase and lowercase letters');\n }\n\n if (/\\d/.test(password)) {\n score += 1;\n } else {\n feedback.push('Include at least one number');\n }\n\n if (/[!@#$%^&*()_+\\-=[\\]{};':\"\\\\|,.<>/?]/.test(password)) {\n score += 1;\n } else {\n feedback.push('Include at least one special character');\n }\n\n return { score, feedback };\n}\n","/**\n * Path utilities for handling navigation in auth flows.\n * Ensures proper path resolution when auth pages are served under a base path (e.g., /auth/)\n */\n\n/**\n * Resolves an auth route path relative to the current location.\n * If the current path is under /auth/, it will preserve that prefix.\n * Otherwise, it returns the path as-is.\n *\n * @param targetPath - The target auth path (e.g., '/sign-in', '/sign-up')\n * @returns The resolved path with proper base path handling\n *\n * @example\n * // Current URL: http://localhost:5174/auth/sign-in\n * resolveAuthPath('/sign-up') // Returns '/auth/sign-up'\n *\n * @example\n * // Current URL: http://localhost:5174/sign-in\n * resolveAuthPath('/sign-up') // Returns '/sign-up'\n */\nexport function resolveAuthPath(targetPath: string): string {\n if (typeof window === 'undefined') {\n return targetPath;\n }\n\n const currentPath = window.location.pathname;\n\n // Check if we're currently under /auth/ base path\n if (currentPath.startsWith('/auth/')) {\n // If target already has /auth/ prefix, return as-is\n if (targetPath.startsWith('/auth/')) {\n return targetPath;\n }\n // Add /auth/ prefix to the target path\n return `/auth${targetPath}`;\n }\n\n // Not under /auth/, return target path as-is\n return targetPath;\n}\n\n/**\n * Resolves an auth route URL with search params preserved.\n * Similar to resolveAuthPath but returns a full URL string with query parameters.\n *\n * @param targetPath - The target auth path (e.g., '/sign-in', '/sign-up')\n * @param searchParams - Optional URLSearchParams to append\n * @returns The resolved URL as a string\n *\n * @example\n * // Current URL: http://localhost:5174/auth/sign-in?redirect=...\n * resolveAuthUrl('/sign-up', searchParams) // Returns '/auth/sign-up?redirect=...'\n */\nexport function resolveAuthUrl(targetPath: string, searchParams?: URLSearchParams): string {\n const resolvedPath = resolveAuthPath(targetPath);\n\n if (!searchParams || searchParams.toString() === '') {\n return resolvedPath;\n }\n\n return `${resolvedPath}?${searchParams.toString()}`;\n}\n","/**\n * Hosted Auth Helpers\n *\n * Utilities for detecting hosted auth environment and building legacy auth URLs\n * for cross-domain authentication flows.\n */\n\n/**\n * Check if current environment is a hosted auth environment\n *\n * Returns true for:\n * - localhost with port 7130 (hosted auth app dev)\n * - https://*.insforge.app (hosted auth app production)\n *\n * @returns true if running in hosted auth environment\n */\nexport function isHostedAuthEnvironment(): boolean {\n if (typeof window === 'undefined') {\n return false;\n }\n\n const { hostname, port, protocol } = window.location;\n\n // Local development\n if (hostname === 'localhost' && port === '7130') {\n return true;\n }\n\n // Production hosted auth\n if (protocol === 'https:' && hostname.endsWith('.insforge.app')) {\n return true;\n }\n\n return false;\n}\n\n/**\n * Session data for building legacy auth URL\n */\nexport interface LegacyAuthSession {\n accessToken: string;\n userId: string;\n email: string;\n name?: string;\n csrfToken?: string;\n}\n\n/**\n * Build a legacy flow redirect URL with auth params in query string\n *\n * This is used to pass authentication credentials back to the user's app\n * after OAuth completes in the hosted auth environment.\n *\n * @param redirectUrl - The URL to redirect to (user's app)\n * @param session - The session data to include in the URL\n * @returns The complete URL with auth params\n */\nexport function buildLegacyAuthUrl(\n redirectUrl: string,\n session: LegacyAuthSession\n): string {\n const url = new URL(redirectUrl);\n url.searchParams.set('access_token', session.accessToken);\n url.searchParams.set('user_id', session.userId);\n url.searchParams.set('email', session.email);\n\n if (session.name) {\n url.searchParams.set('name', session.name);\n }\n\n if (session.csrfToken) {\n url.searchParams.set('csrf_token', session.csrfToken);\n }\n\n return url.toString();\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@insforge/react",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.6-test.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Framework-agnostic React authentication UI components for Insforge - reusable across all frameworks",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -89,7 +89,7 @@
|
|
|
89
89
|
"@emotion/react": "^11.11.1",
|
|
90
90
|
"@emotion/styled": "^11.11.0",
|
|
91
91
|
"@insforge/sdk": "^1.1.2",
|
|
92
|
-
"@insforge/shared": "^1.1.
|
|
92
|
+
"@insforge/shared": "^1.1.4",
|
|
93
93
|
"@insforge/shared-schemas": "^1.1.42",
|
|
94
94
|
"lucide-react": "^0.552.0",
|
|
95
95
|
"zod": "^4.1.12"
|