-
Notifications
You must be signed in to change notification settings - Fork 58
/
Copy pathlogin-oidc.js
102 lines (86 loc) · 3.27 KB
/
login-oidc.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
import Route from '@ember/routing/route';
import { service } from '@ember/service';
import get from 'lodash/get';
import ENV from 'pix-admin/config/environment';
import JSONApiError from 'pix-admin/errors/json-api-error';
export default class LoginOidcRoute extends Route {
@service session;
@service router;
@service location;
@service oidcIdentityProviders;
beforeModel(transition) {
const queryParams = transition.to.queryParams;
if (!queryParams.code) {
this._cleanSession();
const identityProviderSlug = transition.to.params.identity_provider_slug.toString();
const identityProvider = this.oidcIdentityProviders.list.find((provider) => provider.id === identityProviderSlug);
if (identityProvider !== undefined) return this._handleRedirectRequest(identityProvider);
return this.router.replaceWith('login');
}
}
async model(params, transition) {
await this.oidcIdentityProviders.loadReadyIdentityProviders();
const queryParams = transition.to.queryParams;
const identityProviderSlug = params.identity_provider_slug;
if (queryParams.code) {
return this._handleCallbackRequest(queryParams.code, queryParams.state, identityProviderSlug);
}
}
async afterModel({ shouldUserCreateAnAccount, authenticationKey, identityProviderSlug, email } = {}) {
if (!shouldUserCreateAnAccount && !authenticationKey) return;
try {
await this.session.authenticate('authenticator:oidc', {
authenticationKey,
identityProviderSlug,
email,
});
} catch (response) {
const apiError = get(response, 'errors[0]');
const error = new JSONApiError(apiError?.detail, apiError);
let queryParams;
if (error.status === '404' && error.code === 'USER_ACCOUNT_NOT_FOUND') {
queryParams = { userShouldCreateAnAccount: true };
} else {
queryParams = { unknownErrorHasOccured: true };
}
return this.router.replaceWith('login', {
queryParams,
});
}
}
_cleanSession() {
this.session.set('data.nextURL', undefined);
}
async _handleCallbackRequest(code, state, identityProviderSlug) {
try {
await this.session.authenticate('authenticator:oidc', {
code,
state,
identityProviderSlug,
});
} catch (response) {
const apiError = get(response, 'errors[0]');
const error = new JSONApiError(apiError.detail, apiError);
const shouldUserCreateAnAccount = error.code === 'SHOULD_VALIDATE_CGU';
const { authenticationKey, userClaims } = error.meta ?? {};
if (shouldUserCreateAnAccount && authenticationKey) {
return { shouldUserCreateAnAccount, authenticationKey, email: userClaims.email, identityProviderSlug };
}
if (error.status === '403' && error.code === 'PIX_ADMIN_ACCESS_NOT_ALLOWED') {
return this.router.replaceWith('login', {
queryParams: {
userShouldRequestAccess: true,
},
});
}
throw error;
}
}
async _handleRedirectRequest(identityProvider) {
const response = await fetch(
`${ENV.APP.API_HOST}/api/oidc/authorization-url?identity_provider=${identityProvider.code}`,
);
const { redirectTarget } = await response.json();
this.location.replace(redirectTarget);
}
}