@sinequa/atomic-angular 1.6.0 → 1.6.1
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.
|
@@ -10881,6 +10881,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
|
|
|
10881
10881
|
}]
|
|
10882
10882
|
}] });
|
|
10883
10883
|
|
|
10884
|
+
/**
|
|
10885
|
+
* Mirrors @sinequa/atomic's `AUTH_REDIRECT_ATTEMPT_KEY` (src/authentication/constants.ts): the
|
|
10886
|
+
* sessionStorage flag set right before a provider full-page redirect (`window.location.href`).
|
|
10887
|
+
* Reading it lets us tell "an IdP redirect is under way" from "no session", without a blind timer.
|
|
10888
|
+
*/
|
|
10889
|
+
const AUTH_REDIRECT_ATTEMPT_KEY = "sinequa-auth-redirect-attempt";
|
|
10884
10890
|
/**
|
|
10885
10891
|
* Represents the LoginComponent class, which is responsible for handling the login functionality.
|
|
10886
10892
|
* This component is used to authenticate users and manage the user's authentication status.
|
|
@@ -10922,6 +10928,13 @@ class SignInComponent {
|
|
|
10922
10928
|
authenticated = signal(isAuthenticated(), ...(ngDevMode ? [{ debugName: "authenticated" }] : []));
|
|
10923
10929
|
user = signal(getState(this.principalStore), ...(ngDevMode ? [{ debugName: "user" }] : []));
|
|
10924
10930
|
expiresSoonNotified = signal(false, ...(ngDevMode ? [{ debugName: "expiresSoonNotified" }] : []));
|
|
10931
|
+
/**
|
|
10932
|
+
* Forces the credentials form to show even while `externalAuth` is true. Set when a silent
|
|
10933
|
+
* SSO/browser auth attempt fails and no OAuth/SAML provider is configured: in that case
|
|
10934
|
+
* `useSSO` only meant "unknown — try SSO, then credentials", so we fall back to the form
|
|
10935
|
+
* instead of routing to /error.
|
|
10936
|
+
*/
|
|
10937
|
+
showCredentialsFallback = signal(false, ...(ngDevMode ? [{ debugName: "showCredentialsFallback" }] : []));
|
|
10925
10938
|
constructor(destroyRef) {
|
|
10926
10939
|
this.destroyRef = destroyRef;
|
|
10927
10940
|
// If the user is already authenticated when landing here (e.g. page refresh on
|
|
@@ -10931,21 +10944,45 @@ class SignInComponent {
|
|
|
10931
10944
|
const url = this.route.snapshot.queryParams["returnUrl"] || "/";
|
|
10932
10945
|
this.router.navigateByUrl(url);
|
|
10933
10946
|
}
|
|
10934
|
-
// When authentication is delegated to the browser/proxy (SSO) or an OAuth/SAML
|
|
10935
|
-
//
|
|
10936
|
-
//
|
|
10937
|
-
//
|
|
10938
|
-
//
|
|
10947
|
+
// When authentication is delegated to the browser/proxy (SSO) or an OAuth/SAML provider, no
|
|
10948
|
+
// credentials form is shown: this screen shows a loader and starts the handshake automatically.
|
|
10949
|
+
// Drive what happens next from the OUTCOME of `login()`, never a blind timer racing the network
|
|
10950
|
+
// call (the old 5s timer fired while a slow but legitimate provider call — up to its own 10s
|
|
10951
|
+
// network timeout — was still in flight, flashing /error just before the IdP redirect):
|
|
10952
|
+
// • rejected → real failure (network timeout, 5xx, callback loop) → /error WITH the reason;
|
|
10953
|
+
// • resolved true → authenticated → the `authenticated` event / returnUrl drives navigation;
|
|
10954
|
+
// • resolved false → either an OAuth/SAML full-page redirect is under way (the redirect flag was
|
|
10955
|
+
// set just before `window.location.href`; the page is about to unload, so do
|
|
10956
|
+
// nothing and let it leave for the IdP), or no provider is configured
|
|
10957
|
+
// (ambiguous SSO → show the credentials form), or the provider returned no
|
|
10958
|
+
// redirect at all (→ /error).
|
|
10939
10959
|
if (this.externalAuth && !this.authenticated()) {
|
|
10940
|
-
|
|
10960
|
+
login()
|
|
10961
|
+
.then(result => {
|
|
10962
|
+
if (result) {
|
|
10963
|
+
this.auditService.notifyLogin();
|
|
10964
|
+
return;
|
|
10965
|
+
}
|
|
10966
|
+
const hasAutoProvider = !!(globalConfig.autoOAuthProvider || globalConfig.autoSAMLProvider);
|
|
10967
|
+
if (!hasAutoProvider) {
|
|
10968
|
+
this.showCredentialsFallback.set(true);
|
|
10969
|
+
return;
|
|
10970
|
+
}
|
|
10971
|
+
// A full-page redirect to the IdP was initiated → the page is about to unload. Routing to
|
|
10972
|
+
// /error here is exactly what caused the transient "error" flash, so skip it.
|
|
10973
|
+
if (sessionStorage.getItem(AUTH_REDIRECT_ATTEMPT_KEY))
|
|
10974
|
+
return;
|
|
10975
|
+
// Provider configured but the server returned no redirectUrl and there is no session → error.
|
|
10941
10976
|
this.router.navigate(["/error"], {
|
|
10942
10977
|
queryParams: { returnUrl: this.route.snapshot.queryParams["returnUrl"] }
|
|
10943
10978
|
});
|
|
10944
|
-
}
|
|
10945
|
-
|
|
10946
|
-
|
|
10947
|
-
|
|
10948
|
-
|
|
10979
|
+
})
|
|
10980
|
+
.catch((err) => {
|
|
10981
|
+
warn("An error occurred while logging in", err);
|
|
10982
|
+
this.auditService.notify({ type: "Login_Denied" });
|
|
10983
|
+
// Surface the failure reason on the error page (e.g. "OAuth provider not found: identity-dev").
|
|
10984
|
+
const message = (err?.errorMessage ?? err?.message) || undefined;
|
|
10985
|
+
this.router.navigate(["error"], { queryParams: { message } });
|
|
10949
10986
|
});
|
|
10950
10987
|
}
|
|
10951
10988
|
effect(() => {
|
|
@@ -11057,7 +11094,7 @@ class SignInComponent {
|
|
|
11057
11094
|
}
|
|
11058
11095
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: SignInComponent, deps: [{ token: i0.DestroyRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
11059
11096
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: SignInComponent, isStandalone: true, selector: "signIn, signin, sign-in", inputs: { class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, username: { classPropertyName: "username", publicName: "username", isSignal: true, isRequired: false, transformFunction: null }, password: { classPropertyName: "password", publicName: "password", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { forgotPassword: "forgotPassword", username: "usernameChange", password: "passwordChange" }, host: { properties: { "class": "cn('grid h-dvh w-full place-content-center', class())" } }, providers: [provideTranslocoScope("login")], ngImport: i0, template: `
|
|
11060
|
-
@if (!authenticated() && !externalAuth) {
|
|
11097
|
+
@if (!authenticated() && (!externalAuth || showCredentialsFallback())) {
|
|
11061
11098
|
<Card
|
|
11062
11099
|
hover="no"
|
|
11063
11100
|
cdkTrapFocus
|
|
@@ -11130,7 +11167,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
|
|
|
11130
11167
|
CardHeaderComponent,
|
|
11131
11168
|
CardContentComponent
|
|
11132
11169
|
], providers: [provideTranslocoScope("login")], template: `
|
|
11133
|
-
@if (!authenticated() && !externalAuth) {
|
|
11170
|
+
@if (!authenticated() && (!externalAuth || showCredentialsFallback())) {
|
|
11134
11171
|
<Card
|
|
11135
11172
|
hover="no"
|
|
11136
11173
|
cdkTrapFocus
|