@@ -87,13 +87,27 @@ const RLS_MODULE_SQL = `
8787` ;
8888
8989/**
90- * Query auth settings from the tenant DB private schema .
91- * The table name follows the pattern: {privateSchema}.app_settings_auth
92- * We select only the server-relevant columns.
90+ * Discover auth settings table location via metaschema modules .
91+ * Step 1: Get auth_settings_table_id from sessions_module
92+ * Step 2: Resolve the actual schema + table name via metaschema.schema_and_table()
9393 */
94- const AUTH_SETTINGS_SQL = ( privateSchema : string ) => `
94+ const AUTH_SETTINGS_TABLE_ID_SQL = `
95+ SELECT auth_settings_table_id
96+ FROM metaschema_modules_public.sessions_module
97+ LIMIT 1
98+ ` ;
99+
100+ const AUTH_SETTINGS_SCHEMA_AND_TABLE_SQL = `
101+ SELECT schema_name, table_name
102+ FROM metaschema.schema_and_table($1)
103+ ` ;
104+
105+ /**
106+ * Query auth settings from the discovered table.
107+ * Schema and table name are resolved dynamically from metaschema modules.
108+ */
109+ const AUTH_SETTINGS_SQL = ( schemaName : string , tableName : string ) => `
95110 SELECT
96- allowed_origins,
97111 cookie_secure,
98112 cookie_samesite,
99113 cookie_domain,
@@ -102,7 +116,7 @@ const AUTH_SETTINGS_SQL = (privateSchema: string) => `
102116 cookie_path,
103117 enable_captcha,
104118 captcha_site_key
105- FROM "${ privateSchema } ".app_settings_auth
119+ FROM "${ schemaName } "." ${ tableName } "
106120 LIMIT 1
107121` ;
108122
@@ -132,7 +146,6 @@ interface RlsModuleData {
132146}
133147
134148interface AuthSettingsRow {
135- allowed_origins : string [ ] | null ;
136149 cookie_secure : boolean ;
137150 cookie_samesite : string ;
138151 cookie_domain : string | null ;
@@ -243,7 +256,6 @@ const toRlsModule = (row: RlsModuleRow | null): RlsModule | undefined => {
243256const toAuthSettings = ( row : AuthSettingsRow | null ) : AuthSettings | undefined => {
244257 if ( ! row ) return undefined ;
245258 return {
246- allowedOrigins : row . allowed_origins ,
247259 cookieSecure : row . cookie_secure ,
248260 cookieSamesite : row . cookie_samesite ,
249261 cookieDomain : row . cookie_domain ,
@@ -327,23 +339,41 @@ const queryRlsModule = async (pool: Pool, apiId: string): Promise<RlsModuleRow |
327339} ;
328340
329341/**
330- * Load server-relevant auth settings from the tenant DB private schema.
331- * Fails gracefully if the table doesn't exist yet (pre-migration).
342+ * Load server-relevant auth settings from the tenant DB.
343+ * Discovers the auth settings table dynamically by querying
344+ * metaschema_modules_public.sessions_module for the table ID,
345+ * then resolving the actual schema + table name via metaschema.schema_and_table().
346+ * Fails gracefully if modules or table don't exist yet (pre-migration).
332347 */
333348const queryAuthSettings = async (
334349 opts : ApiOptions ,
335- dbname : string ,
336- rlsModuleRow : RlsModuleRow | null
350+ dbname : string
337351) : Promise < AuthSettingsRow | null > => {
338- if ( ! rlsModuleRow ?. data ?. authenticate_schema ) return null ;
339- const privateSchema = rlsModuleRow . data . authenticate_schema ;
340352 try {
341353 const tenantPool = getPgPool ( { ...opts . pg , database : dbname } ) ;
342- const result = await tenantPool . query < AuthSettingsRow > ( AUTH_SETTINGS_SQL ( privateSchema ) ) ;
354+
355+ // Step 1: Get auth_settings_table_id from sessions_module
356+ const modResult = await tenantPool . query < { auth_settings_table_id : string } > ( AUTH_SETTINGS_TABLE_ID_SQL ) ;
357+ const tableId = modResult . rows [ 0 ] ?. auth_settings_table_id ;
358+ if ( ! tableId ) {
359+ log . debug ( '[auth-settings] No sessions_module row found in tenant DB' ) ;
360+ return null ;
361+ }
362+
363+ // Step 2: Resolve actual schema + table name
364+ const stResult = await tenantPool . query < { schema_name : string ; table_name : string } > ( AUTH_SETTINGS_SCHEMA_AND_TABLE_SQL , [ tableId ] ) ;
365+ const resolved = stResult . rows [ 0 ] ;
366+ if ( ! resolved ) {
367+ log . debug ( `[auth-settings] Could not resolve schema_and_table for table_id=${ tableId } ` ) ;
368+ return null ;
369+ }
370+
371+ // Step 3: Query the actual auth settings table
372+ const result = await tenantPool . query < AuthSettingsRow > ( AUTH_SETTINGS_SQL ( resolved . schema_name , resolved . table_name ) ) ;
343373 return result . rows [ 0 ] ?? null ;
344374 } catch ( e : any ) {
345- // Table may not exist yet if the 2FA migration hasn't been applied
346- log . debug ( `[auth-settings] Failed to load auth settings from ${ privateSchema } .app_settings_auth : ${ e . message } ` ) ;
375+ // Table/module may not exist yet if the 2FA migration hasn't been applied
376+ log . debug ( `[auth-settings] Failed to load auth settings: ${ e . message } ` ) ;
347377 return null ;
348378 }
349379} ;
@@ -407,7 +437,7 @@ const resolveApiNameHeader = async (ctx: ResolveContext): Promise<ApiStructure |
407437 }
408438
409439 const rlsModule = await queryRlsModule ( pool , row . api_id ) ;
410- const authSettings = await queryAuthSettings ( opts , row . dbname , rlsModule ) ;
440+ const authSettings = await queryAuthSettings ( opts , row . dbname ) ;
411441 log . debug ( `[api-name-lookup] resolved schemas: [${ row . schemas ?. join ( ', ' ) } ], rlsModule: ${ rlsModule ? 'found' : 'none' } , authSettings: ${ authSettings ? 'found' : 'none' } ` ) ;
412442 return toApiStructure ( row , opts , rlsModule , authSettings ) ;
413443} ;
@@ -433,7 +463,7 @@ const resolveDomainLookup = async (ctx: ResolveContext): Promise<ApiStructure |
433463 }
434464
435465 const rlsModule = await queryRlsModule ( pool , row . api_id ) ;
436- const authSettings = await queryAuthSettings ( opts , row . dbname , rlsModule ) ;
466+ const authSettings = await queryAuthSettings ( opts , row . dbname ) ;
437467 log . debug ( `[domain-lookup] resolved schemas: [${ row . schemas ?. join ( ', ' ) } ], rlsModule: ${ rlsModule ? 'found' : 'none' } , authSettings: ${ authSettings ? 'found' : 'none' } ` ) ;
438468 return toApiStructure ( row , opts , rlsModule , authSettings ) ;
439469} ;
0 commit comments