@@ -531,6 +531,24 @@ component output="false" {
531531 }
532532 }
533533
534+ // Auth wiring facade (enableSession) — same mapping-absolute include
535+ // ladder as the other global files above.
536+ try {
537+ include " /wheels/global/auth.cfm" ;
538+ } catch (any e ) {
539+ if (! $isMissingMappedInclude (e )) {
540+ rethrow ;
541+ }
542+ try {
543+ include " global/auth.cfm" ;
544+ } catch (any e2 ) {
545+ if (! $isMissingMappedInclude (e2 )) {
546+ rethrow ;
547+ }
548+ include " ../vendor/wheels/global/auth.cfm" ;
549+ }
550+ }
551+
534552 // User-defined global functions
535553 try {
536554 include " /app/global/functions.cfm" ;
@@ -564,72 +582,4 @@ component output="false" {
564582 // "The key [...] was not found in the struct. Valid keys are ([VARKEY])".
565583 $promoteIncludedGlobalsToThis ();
566584
567- /**
568- * One-line session-auth wiring for `config/services.cfm`.
569- *
570- * The auth subsystem ships complete (Authenticator strategy registry +
571- * SessionStrategy with login/logout/currentUser and SID rotation) but
572- * wiring it by hand spans two files: map the singletons here, then
573- * register the strategy in `app/events/onapplicationstart.cfm`.
574- * `enableSession()` collapses that into one idempotent call:
575- *
576- * // config/services.cfm
577- * enableSession(sessionKey = "wheels.auth");
578- *
579- * The DI container is available in services.cfm (it is NOT available in
580- * config/app.cfm — services.cfm is loaded after the container is built).
581- * Manual wiring keeps working; this helper is the convenience path.
582- *
583- * Declared as a real method (not an include-injected global): the
584- * include-injection + promotion path proved unreliable on RustCFML's
585- * Linux build, where the function silently went missing from the Global
586- * instance.
587- */
588- public any function enableSession (string sessionKey = " wheels.auth" , any onLogin = " " , any onLogout = " " ) {
589- // Guard: enableSession() belongs in config/services.cfm, where the
590- // container exists. Fail with a pointer rather than an opaque scope
591- // error when it is called from a context without one.
592- try {
593- var di = injector ();
594- } catch (any e ) {
595- Throw (
596- type = " Wheels.Injector" ,
597- message = " enableSession() requires the DI container — call it from config/services.cfm (loaded at application start)." ,
598- detail = e .message
599- );
600- }
601- if (! isObject (di )) {
602- Throw (
603- type = " Wheels.Injector" ,
604- message = " enableSession() requires the DI container — call it from config/services.cfm (loaded at application start)."
605- );
606- }
607-
608- // Map the singletons only when they aren't already mapped, so manual
609- // wiring and repeat calls stay idempotent.
610- if (! di .containsInstance (" authenticator" )) {
611- di .map (" authenticator" ).to (" wheels.auth.Authenticator" ).asSingleton ();
612- }
613- if (! di .containsInstance (" sessionStrategy" )) {
614- di .map (" sessionStrategy" ).to (" wheels.auth.SessionStrategy" ).asSingleton ();
615- }
616-
617- // Resolve with explicit initArguments: the singleton cache honors the
618- // first resolution's arguments, so a custom sessionKey/callbacks stick
619- // even if something else resolved the strategy first with defaults.
620- var authenticator = service (" authenticator" );
621- var strategy = di .getInstance (
622- " sessionStrategy" ,
623- { sessionKey : arguments .sessionKey , onLogin : arguments .onLogin , onLogout : arguments .onLogout }
624- );
625-
626- // Register once. Repeat calls (dev reloads, double-includes) must not
627- // stack duplicate registrations.
628- if (! authenticator .hasStrategy (" session" )) {
629- authenticator .registerStrategy (name = " session" , strategy = strategy );
630- }
631-
632- return strategy ;
633- }
634-
635585}
0 commit comments