Files
frontend-lblod-chat/app/services/session.js
2026-09-16 17:16:19 +02:00

84 lines
3.0 KiB
JavaScript

import { service } from '@ember/service';
import BaseSessionService from 'ember-simple-auth/services/session';
import ENV from 'frontend-lblod-chat/config/environment';
export default class SessionService extends BaseSessionService {
@service currentSession;
@service router;
get isAcmIdmSession() {
if (!this.isAuthenticated) {
return false;
}
return this.data.authenticated.authenticator === 'authenticator:acm-idm';
}
requireAuthentication(transition, routeOrCallback) {
const isAuthenticated = super.requireAuthentication(
transition,
routeOrCallback,
);
// The user isn't authenticated. We store the url in a cookie so we can retry it after logging in.
if (!isAuthenticated) {
// By default ESA only supports retrying transitions by looking at the `attemptedTransition` property.
// However, this property isn't persisted, so after a page reload it is gone, which is an issue for our redirect-based ACM/IDM setup.
// ESA also has a cookie-based redirect setup to support FastBoot. With a little bit of code we can hook into this system
// so the redirect also survives a page reload.
const COOKIE_NAME = 'ember_simple_auth-redirectTarget'; // This is the name that ESA uses: https://github.com/mainmatter/ember-simple-auth/blob/1404c501c2ba9c8c6c071b05f38d42a057522318/packages/ember-simple-auth/src/-internals/routing.js#L37
const redirectUrl = routeInfoUrl(transition.to, this.router);
document.cookie = `${COOKIE_NAME}=${redirectUrl};path=/;samesite=strict`;
}
return isAuthenticated;
}
handleAuthentication(routeAfterAuthentication) {
super.handleAuthentication(routeAfterAuthentication);
this.currentSession.load();
}
invalidate() {
// We store the flag here since the data is cleared before the handleInvalidation method is called.
this.wasAcmIdmSession = this.isAcmIdmSession;
super.invalidate(...arguments);
}
handleInvalidation() {
let logoutUrl;
if (this.wasAcmIdmSession) {
logoutUrl = ENV.acmidm.logoutUrl;
} else {
logoutUrl = this.router.urlFor('mock-login');
}
super.handleInvalidation(logoutUrl);
}
}
// This converts a RouteInfo instance to the corresponding url by collecting all
// the route params and query params and using the router.urlFor method.
// This is a public API reimplementation of the `transition.intent.url` property.
// More info: https://discord.com/channels/480462759797063690/624403666585124895/897832626616926218
function routeInfoUrl(routeInfo, routerService) {
let targetRoute = routeInfo.name;
let allRouteParamValues = [];
let allRouteQueryParams = {};
routeInfo.find((routeInfo) => {
routeInfo.paramNames.forEach((paramName) => {
let paramValue = routeInfo.params[paramName];
allRouteParamValues.push(paramValue);
allRouteQueryParams = {
...allRouteQueryParams,
...routeInfo.queryParams,
};
});
});
return routerService.urlFor(targetRoute, ...allRouteParamValues, {
queryParams: allRouteQueryParams,
});
}