@@ -75,38 +75,113 @@ const formCreationStrategies = [
7575 name : 'Create form by manually defining structure' ,
7676 async run ( ) {
7777 const defaultForm = {
78- id : 'fallback-form-' + Date . now ( ) , // Note: Use only client-side validation
7978 valid : true ,
8079 posted : false ,
81- data : { username : '' , password : '' } ,
8280 errors : { } ,
83- constraints : {
84- username : { minlength : 3 , maxlength : 24 , required : true , pattern : '[\\w]*' } ,
85- password : {
86- minlength : 8 ,
87- maxlength : 128 ,
88- required : true ,
89- pattern : '(?=.*?[a-z])(?=.*?[A-Z])(?=.*?\\d)[a-zA-Z\\d]{8,128}' ,
90- } ,
91- } ,
92- // [Workaround] Critical fix for production environment schema shape error
93- // SuperForms requires a 'shape' property for internal form structure validation
94- // In production builds, Zod schema internals may be optimized away, causing
95- // "SchemaError: No shape could be created for schema" errors
96- //
97- // See:
98- // SuperForms source - schemaShape() function in adapters/zod.ts
99- // https://github.com/ciscoheat/sveltekit-superforms/issues/594
100- shape : {
101- username : { type : 'string' } ,
102- password : { type : 'string' } ,
103- } ,
81+ message : '' ,
82+ ...createBaseAuthForm ( ) ,
10483 } ;
84+
10585 return { form : { ...defaultForm , message : '' } } ;
10686 } ,
10787 } ,
10888] ;
10989
90+ /**
91+ * Validate authentication form data with comprehensive fallback handling
92+ * Tries multiple strategies until one succeeds
93+ *
94+ * @param request - The incoming request containing form data
95+ * @returns Object containing success status and either form or errorResponse
96+ */
97+ export const validateAuthFormWithFallback = async ( request : Request ) => {
98+ for ( const strategy of formValidationStrategies ) {
99+ try {
100+ const result = await strategy . run ( request ) ;
101+ console . log ( `${ strategy . name } successful` ) ;
102+
103+ return result . form ;
104+ } catch ( error ) {
105+ console . warn ( `Failed to ${ strategy . name } ` ) ;
106+
107+ if ( error instanceof Error ) {
108+ console . warn ( 'Error:' , error . message ) ;
109+ }
110+ }
111+ }
112+
113+ // This should never be reached due to fallback strategy
114+ throw new Error ( 'Failed to validate form for authentication.' ) ;
115+ } ;
116+
117+ /**
118+ * Form validation strategies for action handlers
119+ * Each strategy attempts a different approach to validate form data from requests
120+ */
121+ const formValidationStrategies = [
122+ {
123+ name : '(Basic Case) Use standard superValidate with request' ,
124+ async run ( request : Request ) {
125+ const form = await superValidate ( request , zod ( authSchema ) ) ;
126+ return { form : { ...form , message : '' } } ;
127+ } ,
128+ } ,
129+ {
130+ name : 'Use zod adapter explicitly with request' ,
131+ async run ( request : Request ) {
132+ const zodAdapter = zod ( authSchema ) ;
133+ const form = await superValidate ( request , zodAdapter ) ;
134+ return { form : { ...form , message : '' } } ;
135+ } ,
136+ } ,
137+ {
138+ name : 'Create fallback form manually' ,
139+ async run ( request : Request ) {
140+ // Create a fallback form with error state
141+ // This maintains consistency with other strategies by returning { form }
142+ const fallbackForm = {
143+ valid : false ,
144+ posted : true ,
145+ errors : { _form : [ 'ログインできませんでした。' ] } ,
146+ message : 'サーバでエラーが発生しました。本サービスの開発・運営チームまでご連絡ください。' ,
147+ ...createBaseAuthForm ( ) ,
148+ } ;
149+
150+ return { form : { ...fallbackForm , message : '' } } ;
151+ } ,
152+ } ,
153+ ] ;
154+
155+ /**
156+ * Common form structure for authentication forms
157+ * Contains constraints and shape definitions used across different form strategies
158+ */
159+ const createBaseAuthForm = ( ) => ( {
160+ id : 'error-fallback-form-' + Date . now ( ) , // Note: Use only client-side validation
161+ data : { username : '' , password : '' } ,
162+ constraints : {
163+ username : { minlength : 3 , maxlength : 24 , required : true , pattern : '[\\w]*' } ,
164+ password : {
165+ minlength : 8 ,
166+ maxlength : 128 ,
167+ required : true ,
168+ pattern : '(?=.*?[a-z])(?=.*?[A-Z])(?=.*?\\d)[a-zA-Z\\d]{8,128}' ,
169+ } ,
170+ } ,
171+ // [Workaround] Critical fix for production environment schema shape error
172+ // SuperForms requires a 'shape' property for internal form structure validation
173+ // In production builds, Zod schema internals may be optimized away, causing
174+ // "SchemaError: No shape could be created for schema" errors
175+ //
176+ // See:
177+ // SuperForms source - schemaShape() function in adapters/zod.ts
178+ // https://github.com/ciscoheat/sveltekit-superforms/issues/594
179+ shape : {
180+ username : { type : 'string' } ,
181+ password : { type : 'string' } ,
182+ } ,
183+ } ) ;
184+
110185export const ensureSessionOrRedirect = async ( locals : App . Locals ) : Promise < void > => {
111186 const session = await locals . auth . validate ( ) ;
112187
0 commit comments