feat: Add OIDC debug mode
This commit is contained in:
@@ -54,6 +54,13 @@ authenticateWithOidc.failure = (error, terms) => ({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
authenticateWithOidc.debug = (logs) => ({
|
||||||
|
type: ActionTypes.WITH_OIDC_AUTHENTICATE__DEBUG,
|
||||||
|
payload: {
|
||||||
|
logs,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const clearAuthenticateError = () => ({
|
const clearAuthenticateError = () => ({
|
||||||
type: ActionTypes.AUTHENTICATE_ERROR_CLEAR,
|
type: ActionTypes.AUTHENTICATE_ERROR_CLEAR,
|
||||||
payload: {},
|
payload: {},
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ const createAccessToken = (data, headers) =>
|
|||||||
const exchangeForAccessTokenWithOidc = (data, headers) =>
|
const exchangeForAccessTokenWithOidc = (data, headers) =>
|
||||||
http.post('/access-tokens/exchange-with-oidc?withHttpOnlyToken=true', data, headers);
|
http.post('/access-tokens/exchange-with-oidc?withHttpOnlyToken=true', data, headers);
|
||||||
|
|
||||||
|
const debugOidc = (data, headers) => http.post('/access-tokens/debug-oidc', data, headers);
|
||||||
|
|
||||||
// TODO: rename?
|
// TODO: rename?
|
||||||
const acceptTerms = (data, headers) => http.post('/access-tokens/accept-terms', data, headers);
|
const acceptTerms = (data, headers) => http.post('/access-tokens/accept-terms', data, headers);
|
||||||
|
|
||||||
@@ -24,6 +26,7 @@ const deleteCurrentAccessToken = (headers) => http.delete('/access-tokens/me', u
|
|||||||
export default {
|
export default {
|
||||||
createAccessToken,
|
createAccessToken,
|
||||||
exchangeForAccessTokenWithOidc,
|
exchangeForAccessTokenWithOidc,
|
||||||
|
debugOidc,
|
||||||
acceptTerms,
|
acceptTerms,
|
||||||
revokePendingToken,
|
revokePendingToken,
|
||||||
deleteCurrentAccessToken,
|
deleteCurrentAccessToken,
|
||||||
|
|||||||
@@ -8,7 +8,8 @@ import React, { useCallback, useEffect, useMemo } from 'react';
|
|||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { useDispatch, useSelector } from 'react-redux';
|
import { useDispatch, useSelector } from 'react-redux';
|
||||||
import { useTranslation, Trans } from 'react-i18next';
|
import { useTranslation, Trans } from 'react-i18next';
|
||||||
import { Button, Divider, Form, Grid, Header, Message } from 'semantic-ui-react';
|
import TextareaAutosize from 'react-textarea-autosize';
|
||||||
|
import { Button, Divider, Form, Grid, Header, Message, TextArea } from 'semantic-ui-react';
|
||||||
import { useDidUpdate, usePrevious, useToggle } from '../../../lib/hooks';
|
import { useDidUpdate, usePrevious, useToggle } from '../../../lib/hooks';
|
||||||
import { Input } from '../../../lib/custom-ui';
|
import { Input } from '../../../lib/custom-ui';
|
||||||
|
|
||||||
@@ -23,7 +24,7 @@ import logo from '../../../assets/images/logo.png';
|
|||||||
|
|
||||||
import styles from './Content.module.scss';
|
import styles from './Content.module.scss';
|
||||||
|
|
||||||
const createMessage = (error) => {
|
const createMessage = (error, isDebug) => {
|
||||||
if (!error) {
|
if (!error) {
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
@@ -82,7 +83,7 @@ const createMessage = (error) => {
|
|||||||
default:
|
default:
|
||||||
return {
|
return {
|
||||||
type: 'warning',
|
type: 'warning',
|
||||||
content: 'common.unknownError',
|
content: isDebug ? error.message : 'common.unknownError',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -95,6 +96,7 @@ const Content = React.memo(() => {
|
|||||||
isSubmitting,
|
isSubmitting,
|
||||||
isSubmittingWithOidc,
|
isSubmittingWithOidc,
|
||||||
error,
|
error,
|
||||||
|
debugLogs,
|
||||||
step,
|
step,
|
||||||
} = useSelector(selectors.selectAuthenticateForm);
|
} = useSelector(selectors.selectAuthenticateForm);
|
||||||
|
|
||||||
@@ -124,7 +126,11 @@ const Content = React.memo(() => {
|
|||||||
return initialData;
|
return initialData;
|
||||||
});
|
});
|
||||||
|
|
||||||
const message = useMemo(() => createMessage(error), [error]);
|
const withOidc = !!bootstrap.oidc;
|
||||||
|
const isOidcEnforced = withOidc && bootstrap.oidc.isEnforced;
|
||||||
|
const isOidcDebug = withOidc && bootstrap.oidc.debug;
|
||||||
|
|
||||||
|
const message = useMemo(() => createMessage(error, isOidcDebug), [error, isOidcDebug]);
|
||||||
const [focusPasswordFieldState, focusPasswordField] = useToggle();
|
const [focusPasswordFieldState, focusPasswordField] = useToggle();
|
||||||
|
|
||||||
const [emailOrUsernameFieldRef, handleEmailOrUsernameFieldRef] = useNestedRef('inputRef');
|
const [emailOrUsernameFieldRef, handleEmailOrUsernameFieldRef] = useNestedRef('inputRef');
|
||||||
@@ -157,14 +163,11 @@ const Content = React.memo(() => {
|
|||||||
dispatch(entryActions.clearAuthenticateError());
|
dispatch(entryActions.clearAuthenticateError());
|
||||||
}, [dispatch]);
|
}, [dispatch]);
|
||||||
|
|
||||||
const withOidc = !!bootstrap.oidc;
|
|
||||||
const isOidcEnforced = withOidc && bootstrap.oidc.isEnforced;
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!isOidcEnforced) {
|
if (!isOidcEnforced) {
|
||||||
emailOrUsernameFieldRef.current.focus();
|
emailOrUsernameFieldRef.current.focus();
|
||||||
}
|
}
|
||||||
}, [emailOrUsernameFieldRef, isOidcEnforced]);
|
}, [isOidcEnforced, emailOrUsernameFieldRef]);
|
||||||
|
|
||||||
useDidUpdate(() => {
|
useDidUpdate(() => {
|
||||||
if (wasSubmitting && !isSubmitting && error) {
|
if (wasSubmitting && !isSubmitting && error) {
|
||||||
@@ -269,16 +272,27 @@ const Content = React.memo(() => {
|
|||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{withOidc && (
|
{withOidc && (
|
||||||
<Button
|
<>
|
||||||
fluid
|
<Button
|
||||||
primary={isOidcEnforced}
|
fluid
|
||||||
icon={isOidcEnforced ? 'right arrow' : undefined}
|
primary={isOidcDebug ? undefined : isOidcEnforced}
|
||||||
labelPosition={isOidcEnforced ? 'right' : undefined}
|
color={isOidcDebug ? 'orange' : undefined}
|
||||||
content={t('action.logInWithSso')}
|
icon={isOidcEnforced ? 'right arrow' : undefined}
|
||||||
loading={isSubmittingWithOidc}
|
labelPosition={isOidcEnforced ? 'right' : undefined}
|
||||||
disabled={isSubmitting || isSubmittingWithOidc}
|
content={isOidcDebug ? t('action.debugSso') : t('action.logInWithSso')}
|
||||||
onClick={handleAuthenticateWithOidcClick}
|
loading={isSubmittingWithOidc}
|
||||||
/>
|
disabled={isSubmitting || isSubmittingWithOidc}
|
||||||
|
onClick={handleAuthenticateWithOidcClick}
|
||||||
|
/>
|
||||||
|
{debugLogs && (
|
||||||
|
<TextArea
|
||||||
|
readOnly
|
||||||
|
as={TextareaAutosize}
|
||||||
|
value={debugLogs.join('\n')}
|
||||||
|
className={styles.debugLog}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className={styles.poweredBy}>
|
<div className={styles.poweredBy}>
|
||||||
|
|||||||
@@ -19,6 +19,16 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.debugLog {
|
||||||
|
border: 1px solid rgba(9, 30, 66, 0.13);
|
||||||
|
border-radius: 3px;
|
||||||
|
color: #333;
|
||||||
|
line-height: 1.4;
|
||||||
|
margin-top: 16px;
|
||||||
|
padding: 8px 12px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.divider {
|
.divider {
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ export default {
|
|||||||
WITH_OIDC_AUTHENTICATE: 'WITH_OIDC_AUTHENTICATE',
|
WITH_OIDC_AUTHENTICATE: 'WITH_OIDC_AUTHENTICATE',
|
||||||
WITH_OIDC_AUTHENTICATE__SUCCESS: 'WITH_OIDC_AUTHENTICATE__SUCCESS',
|
WITH_OIDC_AUTHENTICATE__SUCCESS: 'WITH_OIDC_AUTHENTICATE__SUCCESS',
|
||||||
WITH_OIDC_AUTHENTICATE__FAILURE: 'WITH_OIDC_AUTHENTICATE__FAILURE',
|
WITH_OIDC_AUTHENTICATE__FAILURE: 'WITH_OIDC_AUTHENTICATE__FAILURE',
|
||||||
|
WITH_OIDC_AUTHENTICATE__DEBUG: 'WITH_OIDC_AUTHENTICATE__DEBUG',
|
||||||
AUTHENTICATE_ERROR_CLEAR: 'AUTHENTICATE_ERROR_CLEAR',
|
AUTHENTICATE_ERROR_CLEAR: 'AUTHENTICATE_ERROR_CLEAR',
|
||||||
TERMS_ACCEPT: 'TERMS_ACCEPT',
|
TERMS_ACCEPT: 'TERMS_ACCEPT',
|
||||||
TERMS_ACCEPT__SUCCESS: 'TERMS_ACCEPT__SUCCESS',
|
TERMS_ACCEPT__SUCCESS: 'TERMS_ACCEPT__SUCCESS',
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ export default {
|
|||||||
action: {
|
action: {
|
||||||
cancelAndClose: 'إلغاء وإغلاق',
|
cancelAndClose: 'إلغاء وإغلاق',
|
||||||
continue: 'متابعة',
|
continue: 'متابعة',
|
||||||
|
debugSso: 'تصحيح أخطاء تسجيل الدخول الموحد',
|
||||||
goBack: 'العودة',
|
goBack: 'العودة',
|
||||||
goHome: 'الذهاب للرئيسية',
|
goHome: 'الذهاب للرئيسية',
|
||||||
logIn: 'تسجيل الدخول',
|
logIn: 'تسجيل الدخول',
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ export default {
|
|||||||
action: {
|
action: {
|
||||||
cancelAndClose: 'Отказ и затваряне',
|
cancelAndClose: 'Отказ и затваряне',
|
||||||
continue: 'Продължи',
|
continue: 'Продължи',
|
||||||
|
debugSso: 'Дебъгване на SSO',
|
||||||
goBack: 'Назад',
|
goBack: 'Назад',
|
||||||
goHome: 'Към началото',
|
goHome: 'Към началото',
|
||||||
logIn: 'Вход',
|
logIn: 'Вход',
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ export default {
|
|||||||
action: {
|
action: {
|
||||||
cancelAndClose: 'Cancel·lar i tancar',
|
cancelAndClose: 'Cancel·lar i tancar',
|
||||||
continue: 'Continuar',
|
continue: 'Continuar',
|
||||||
|
debugSso: 'Depurar SSO',
|
||||||
goBack: 'Tornar',
|
goBack: 'Tornar',
|
||||||
goHome: "Anar a l'inici",
|
goHome: "Anar a l'inici",
|
||||||
logIn: 'Iniciar sessió',
|
logIn: 'Iniciar sessió',
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ export default {
|
|||||||
action: {
|
action: {
|
||||||
cancelAndClose: 'Zrušit a zavřít',
|
cancelAndClose: 'Zrušit a zavřít',
|
||||||
continue: 'Pokračovat',
|
continue: 'Pokračovat',
|
||||||
|
debugSso: 'Ladit SSO',
|
||||||
goBack: 'Zpět',
|
goBack: 'Zpět',
|
||||||
goHome: 'Domů',
|
goHome: 'Domů',
|
||||||
logIn: 'Přihlásit se',
|
logIn: 'Přihlásit se',
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ export default {
|
|||||||
action: {
|
action: {
|
||||||
cancelAndClose: 'Annuller og luk',
|
cancelAndClose: 'Annuller og luk',
|
||||||
continue: 'Fortsæt',
|
continue: 'Fortsæt',
|
||||||
|
debugSso: 'Fejlfind SSO',
|
||||||
goBack: 'Gå tilbage',
|
goBack: 'Gå tilbage',
|
||||||
goHome: 'Gå hjem',
|
goHome: 'Gå hjem',
|
||||||
logIn: 'Log på',
|
logIn: 'Log på',
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ export default {
|
|||||||
action: {
|
action: {
|
||||||
cancelAndClose: 'Abbrechen und schließen',
|
cancelAndClose: 'Abbrechen und schließen',
|
||||||
continue: 'Fortfahren',
|
continue: 'Fortfahren',
|
||||||
|
debugSso: 'SSO debuggen',
|
||||||
goBack: 'Zurück gehen',
|
goBack: 'Zurück gehen',
|
||||||
goHome: 'Zur Startseite',
|
goHome: 'Zur Startseite',
|
||||||
logIn: 'Einloggen',
|
logIn: 'Einloggen',
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ export default {
|
|||||||
action: {
|
action: {
|
||||||
cancelAndClose: 'Ακύρωση και κλείσιμο',
|
cancelAndClose: 'Ακύρωση και κλείσιμο',
|
||||||
continue: 'Συνέχεια',
|
continue: 'Συνέχεια',
|
||||||
|
debugSso: 'Αποσφαλμάτωση SSO',
|
||||||
goBack: 'Επιστροφή',
|
goBack: 'Επιστροφή',
|
||||||
goHome: 'Αρχική σελίδα',
|
goHome: 'Αρχική σελίδα',
|
||||||
logIn: 'Σύνδεση',
|
logIn: 'Σύνδεση',
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ export default {
|
|||||||
action: {
|
action: {
|
||||||
cancelAndClose: 'Cancel and close',
|
cancelAndClose: 'Cancel and close',
|
||||||
continue: 'Continue',
|
continue: 'Continue',
|
||||||
|
debugSso: 'Debug SSO',
|
||||||
goBack: 'Go back',
|
goBack: 'Go back',
|
||||||
goHome: 'Go home',
|
goHome: 'Go home',
|
||||||
logIn: 'Log in',
|
logIn: 'Log in',
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ export default {
|
|||||||
action: {
|
action: {
|
||||||
cancelAndClose: 'Cancel and close',
|
cancelAndClose: 'Cancel and close',
|
||||||
continue: 'Continue',
|
continue: 'Continue',
|
||||||
|
debugSso: 'Debug SSO',
|
||||||
goBack: 'Go back',
|
goBack: 'Go back',
|
||||||
goHome: 'Go home',
|
goHome: 'Go home',
|
||||||
logIn: 'Log in',
|
logIn: 'Log in',
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ export default {
|
|||||||
action: {
|
action: {
|
||||||
cancelAndClose: 'Cancelar y cerrar',
|
cancelAndClose: 'Cancelar y cerrar',
|
||||||
continue: 'Continuar',
|
continue: 'Continuar',
|
||||||
|
debugSso: 'Depurar SSO',
|
||||||
goBack: 'Volver',
|
goBack: 'Volver',
|
||||||
goHome: 'Ir al inicio',
|
goHome: 'Ir al inicio',
|
||||||
logIn: 'Iniciar sesión',
|
logIn: 'Iniciar sesión',
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ export default {
|
|||||||
action: {
|
action: {
|
||||||
cancelAndClose: 'Tühista ja sulge',
|
cancelAndClose: 'Tühista ja sulge',
|
||||||
continue: 'Jätka',
|
continue: 'Jätka',
|
||||||
|
debugSso: 'Siluda SSO',
|
||||||
goBack: 'Tagasi',
|
goBack: 'Tagasi',
|
||||||
goHome: 'Koju',
|
goHome: 'Koju',
|
||||||
logIn: 'Logi sisse',
|
logIn: 'Logi sisse',
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ export default {
|
|||||||
action: {
|
action: {
|
||||||
cancelAndClose: 'لغو و بستن',
|
cancelAndClose: 'لغو و بستن',
|
||||||
continue: 'ادامه',
|
continue: 'ادامه',
|
||||||
|
debugSso: 'اشکالزدایی SSO',
|
||||||
goBack: 'بازگشت',
|
goBack: 'بازگشت',
|
||||||
goHome: 'رفتن به خانه',
|
goHome: 'رفتن به خانه',
|
||||||
logIn: 'ورود',
|
logIn: 'ورود',
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ export default {
|
|||||||
action: {
|
action: {
|
||||||
cancelAndClose: 'Peruuta ja sulje',
|
cancelAndClose: 'Peruuta ja sulje',
|
||||||
continue: 'Jatka',
|
continue: 'Jatka',
|
||||||
|
debugSso: 'Korjaa SSO-virheitä',
|
||||||
goBack: 'Takaisin',
|
goBack: 'Takaisin',
|
||||||
goHome: 'Kotiin',
|
goHome: 'Kotiin',
|
||||||
logIn: 'Kirjaudu sisään',
|
logIn: 'Kirjaudu sisään',
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ export default {
|
|||||||
action: {
|
action: {
|
||||||
cancelAndClose: 'Annuler et fermer',
|
cancelAndClose: 'Annuler et fermer',
|
||||||
continue: 'Continuer',
|
continue: 'Continuer',
|
||||||
|
debugSso: 'Déboguer le SSO',
|
||||||
goBack: 'Retour',
|
goBack: 'Retour',
|
||||||
goHome: "Aller à l'accueil",
|
goHome: "Aller à l'accueil",
|
||||||
logIn: 'Se connecter',
|
logIn: 'Se connecter',
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ export default {
|
|||||||
action: {
|
action: {
|
||||||
cancelAndClose: 'Mégse és bezárás',
|
cancelAndClose: 'Mégse és bezárás',
|
||||||
continue: 'Folytatás',
|
continue: 'Folytatás',
|
||||||
|
debugSso: 'SSO hibakeresése',
|
||||||
goBack: 'Vissza',
|
goBack: 'Vissza',
|
||||||
goHome: 'Kezdőlapra',
|
goHome: 'Kezdőlapra',
|
||||||
logIn: 'Belépés',
|
logIn: 'Belépés',
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ export default {
|
|||||||
action: {
|
action: {
|
||||||
cancelAndClose: 'Batal dan tutup',
|
cancelAndClose: 'Batal dan tutup',
|
||||||
continue: 'Lanjutkan',
|
continue: 'Lanjutkan',
|
||||||
|
debugSso: 'Debug SSO',
|
||||||
goBack: 'Kembali',
|
goBack: 'Kembali',
|
||||||
goHome: 'Ke beranda',
|
goHome: 'Ke beranda',
|
||||||
logIn: 'Masuk',
|
logIn: 'Masuk',
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ export default {
|
|||||||
action: {
|
action: {
|
||||||
cancelAndClose: 'Annulla e chiudi',
|
cancelAndClose: 'Annulla e chiudi',
|
||||||
continue: 'Continua',
|
continue: 'Continua',
|
||||||
|
debugSso: 'Debug SSO',
|
||||||
goBack: 'Torna indietro',
|
goBack: 'Torna indietro',
|
||||||
goHome: 'Vai alla home',
|
goHome: 'Vai alla home',
|
||||||
logIn: 'Accedi',
|
logIn: 'Accedi',
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ export default {
|
|||||||
action: {
|
action: {
|
||||||
cancelAndClose: 'キャンセルして閉じる',
|
cancelAndClose: 'キャンセルして閉じる',
|
||||||
continue: '続行',
|
continue: '続行',
|
||||||
|
debugSso: 'SSOをデバッグ',
|
||||||
goBack: '戻る',
|
goBack: '戻る',
|
||||||
goHome: 'ホームへ',
|
goHome: 'ホームへ',
|
||||||
logIn: 'ログイン',
|
logIn: 'ログイン',
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ export default {
|
|||||||
action: {
|
action: {
|
||||||
cancelAndClose: '취소 후 닫기',
|
cancelAndClose: '취소 후 닫기',
|
||||||
continue: '계속',
|
continue: '계속',
|
||||||
|
debugSso: 'SSO 디버그',
|
||||||
goBack: '뒤로 가기',
|
goBack: '뒤로 가기',
|
||||||
goHome: '홈으로 가기',
|
goHome: '홈으로 가기',
|
||||||
logIn: '로그인',
|
logIn: '로그인',
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ export default {
|
|||||||
action: {
|
action: {
|
||||||
cancelAndClose: 'Annuleren en sluiten',
|
cancelAndClose: 'Annuleren en sluiten',
|
||||||
continue: 'Doorgaan',
|
continue: 'Doorgaan',
|
||||||
|
debugSso: 'SSO debuggen',
|
||||||
goBack: 'Terug gaan',
|
goBack: 'Terug gaan',
|
||||||
goHome: 'Naar startpagina',
|
goHome: 'Naar startpagina',
|
||||||
logIn: 'Inloggen',
|
logIn: 'Inloggen',
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ export default {
|
|||||||
action: {
|
action: {
|
||||||
cancelAndClose: 'Anuluj i zamknij',
|
cancelAndClose: 'Anuluj i zamknij',
|
||||||
continue: 'Kontynuuj',
|
continue: 'Kontynuuj',
|
||||||
|
debugSso: 'Debuguj SSO',
|
||||||
goBack: 'Wróć',
|
goBack: 'Wróć',
|
||||||
goHome: 'Idź do domu',
|
goHome: 'Idź do domu',
|
||||||
logIn: 'Zaloguj',
|
logIn: 'Zaloguj',
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ export default {
|
|||||||
action: {
|
action: {
|
||||||
cancelAndClose: 'Cancelar e fechar',
|
cancelAndClose: 'Cancelar e fechar',
|
||||||
continue: 'Continuar',
|
continue: 'Continuar',
|
||||||
|
debugSso: 'Depurar SSO',
|
||||||
goBack: 'Voltar',
|
goBack: 'Voltar',
|
||||||
goHome: 'Ir para início',
|
goHome: 'Ir para início',
|
||||||
logIn: 'Entrar',
|
logIn: 'Entrar',
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ export default {
|
|||||||
action: {
|
action: {
|
||||||
cancelAndClose: 'Cancelar e fechar',
|
cancelAndClose: 'Cancelar e fechar',
|
||||||
continue: 'Continuar',
|
continue: 'Continuar',
|
||||||
|
debugSso: 'Depurar SSO',
|
||||||
goBack: 'Voltar',
|
goBack: 'Voltar',
|
||||||
goHome: 'Ir para início',
|
goHome: 'Ir para início',
|
||||||
logIn: 'Iniciar sessão',
|
logIn: 'Iniciar sessão',
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ export default {
|
|||||||
action: {
|
action: {
|
||||||
cancelAndClose: 'Anulează și închide',
|
cancelAndClose: 'Anulează și închide',
|
||||||
continue: 'Continuă',
|
continue: 'Continuă',
|
||||||
|
debugSso: 'Depanează SSO',
|
||||||
goBack: 'Înapoi',
|
goBack: 'Înapoi',
|
||||||
goHome: 'Acasă',
|
goHome: 'Acasă',
|
||||||
logIn: 'Autentificarea',
|
logIn: 'Autentificarea',
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ export default {
|
|||||||
action: {
|
action: {
|
||||||
cancelAndClose: 'Отменить и закрыть',
|
cancelAndClose: 'Отменить и закрыть',
|
||||||
continue: 'Продолжить',
|
continue: 'Продолжить',
|
||||||
|
debugSso: 'Отладить SSO',
|
||||||
goBack: 'Назад',
|
goBack: 'Назад',
|
||||||
goHome: 'На главную',
|
goHome: 'На главную',
|
||||||
logIn: 'Войти',
|
logIn: 'Войти',
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ export default {
|
|||||||
action: {
|
action: {
|
||||||
cancelAndClose: 'Zrušiť a zavrieť',
|
cancelAndClose: 'Zrušiť a zavrieť',
|
||||||
continue: 'Pokračovať',
|
continue: 'Pokračovať',
|
||||||
|
debugSso: 'Ladiť SSO',
|
||||||
goBack: 'Ísť späť',
|
goBack: 'Ísť späť',
|
||||||
goHome: 'Ísť domov',
|
goHome: 'Ísť domov',
|
||||||
logIn: 'Prihlásiť sa',
|
logIn: 'Prihlásiť sa',
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ export default {
|
|||||||
action: {
|
action: {
|
||||||
cancelAndClose: 'Откажи и затвори',
|
cancelAndClose: 'Откажи и затвори',
|
||||||
continue: 'Настави',
|
continue: 'Настави',
|
||||||
|
debugSso: 'Дебагуј SSO',
|
||||||
goBack: 'Назад',
|
goBack: 'Назад',
|
||||||
goHome: 'Иди кући',
|
goHome: 'Иди кући',
|
||||||
logIn: 'Пријава',
|
logIn: 'Пријава',
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ export default {
|
|||||||
action: {
|
action: {
|
||||||
cancelAndClose: 'Otkaži i zatvori',
|
cancelAndClose: 'Otkaži i zatvori',
|
||||||
continue: 'Nastavi',
|
continue: 'Nastavi',
|
||||||
|
debugSso: 'Debaguj SSO',
|
||||||
goBack: 'Nazad',
|
goBack: 'Nazad',
|
||||||
goHome: 'Idi kući',
|
goHome: 'Idi kući',
|
||||||
logIn: 'Prijava',
|
logIn: 'Prijava',
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ export default {
|
|||||||
action: {
|
action: {
|
||||||
cancelAndClose: 'Avbryt och stäng',
|
cancelAndClose: 'Avbryt och stäng',
|
||||||
continue: 'Fortsätt',
|
continue: 'Fortsätt',
|
||||||
|
debugSso: 'Felsök SSO',
|
||||||
goBack: 'Gå tillbaka',
|
goBack: 'Gå tillbaka',
|
||||||
goHome: 'Gå hem',
|
goHome: 'Gå hem',
|
||||||
logIn: 'Logga in',
|
logIn: 'Logga in',
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ export default {
|
|||||||
action: {
|
action: {
|
||||||
cancelAndClose: 'İptal et ve kapat',
|
cancelAndClose: 'İptal et ve kapat',
|
||||||
continue: 'Devam et',
|
continue: 'Devam et',
|
||||||
|
debugSso: 'SSO hatalarını ayıkla',
|
||||||
goBack: 'Geri dön',
|
goBack: 'Geri dön',
|
||||||
goHome: 'Ana sayfaya git',
|
goHome: 'Ana sayfaya git',
|
||||||
logIn: 'Giriş yap',
|
logIn: 'Giriş yap',
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ export default {
|
|||||||
action: {
|
action: {
|
||||||
cancelAndClose: 'Скасувати та закрити',
|
cancelAndClose: 'Скасувати та закрити',
|
||||||
continue: 'Продовжити',
|
continue: 'Продовжити',
|
||||||
|
debugSso: 'Відлагодити SSO',
|
||||||
goBack: 'Назад',
|
goBack: 'Назад',
|
||||||
goHome: 'На головну',
|
goHome: 'На головну',
|
||||||
logIn: 'Увійти',
|
logIn: 'Увійти',
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ export default {
|
|||||||
action: {
|
action: {
|
||||||
cancelAndClose: 'Bekor qilish va yopish',
|
cancelAndClose: 'Bekor qilish va yopish',
|
||||||
continue: 'Davom etish',
|
continue: 'Davom etish',
|
||||||
|
debugSso: 'SSO ni tuzatish',
|
||||||
goBack: 'Orqaga',
|
goBack: 'Orqaga',
|
||||||
goHome: 'Bosh sahifaga',
|
goHome: 'Bosh sahifaga',
|
||||||
logIn: 'Kirish',
|
logIn: 'Kirish',
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ export default {
|
|||||||
action: {
|
action: {
|
||||||
cancelAndClose: 'Hủy và đóng',
|
cancelAndClose: 'Hủy và đóng',
|
||||||
continue: 'Tiếp tục',
|
continue: 'Tiếp tục',
|
||||||
|
debugSso: 'Gỡ lỗi SSO',
|
||||||
goBack: 'Quay lại',
|
goBack: 'Quay lại',
|
||||||
goHome: 'Về trang chủ',
|
goHome: 'Về trang chủ',
|
||||||
logIn: 'Đăng nhập',
|
logIn: 'Đăng nhập',
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ export default {
|
|||||||
action: {
|
action: {
|
||||||
cancelAndClose: '取消并关闭',
|
cancelAndClose: '取消并关闭',
|
||||||
continue: '继续',
|
continue: '继续',
|
||||||
|
debugSso: '调试SSO',
|
||||||
goBack: '返回',
|
goBack: '返回',
|
||||||
goHome: '回到首页',
|
goHome: '回到首页',
|
||||||
logIn: '登录',
|
logIn: '登录',
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ export default {
|
|||||||
action: {
|
action: {
|
||||||
cancelAndClose: '取消並關閉',
|
cancelAndClose: '取消並關閉',
|
||||||
continue: '繼續',
|
continue: '繼續',
|
||||||
|
debugSso: '偵錯SSO',
|
||||||
goBack: '返回',
|
goBack: '返回',
|
||||||
goHome: '回到首頁',
|
goHome: '回到首頁',
|
||||||
logIn: '登入',
|
logIn: '登入',
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ const initialState = {
|
|||||||
isSubmitting: false,
|
isSubmitting: false,
|
||||||
isSubmittingWithOidc: false,
|
isSubmittingWithOidc: false,
|
||||||
error: null,
|
error: null,
|
||||||
|
debugLogs: null,
|
||||||
pendingToken: null,
|
pendingToken: null,
|
||||||
step: null,
|
step: null,
|
||||||
termsForm: {
|
termsForm: {
|
||||||
@@ -91,6 +92,12 @@ export default (state = initialState, { type, payload }) => {
|
|||||||
isSubmittingWithOidc: false,
|
isSubmittingWithOidc: false,
|
||||||
error: payload.error,
|
error: payload.error,
|
||||||
};
|
};
|
||||||
|
case ActionTypes.WITH_OIDC_AUTHENTICATE__DEBUG:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
isSubmittingWithOidc: false,
|
||||||
|
debugLogs: payload.logs,
|
||||||
|
};
|
||||||
case ActionTypes.AUTHENTICATE_ERROR_CLEAR:
|
case ActionTypes.AUTHENTICATE_ERROR_CLEAR:
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
|
|||||||
@@ -106,6 +106,20 @@ export function* authenticateWithOidcCallback() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const oidcBootstrap = yield select(selectors.selectOidcBootstrap);
|
||||||
|
|
||||||
|
if (oidcBootstrap?.debug) {
|
||||||
|
const {
|
||||||
|
included: { logs },
|
||||||
|
} = yield call(api.debugOidc, {
|
||||||
|
code,
|
||||||
|
nonce,
|
||||||
|
});
|
||||||
|
|
||||||
|
yield put(actions.authenticateWithOidc.debug(logs));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let accessToken;
|
let accessToken;
|
||||||
try {
|
try {
|
||||||
({ item: accessToken } = yield call(api.exchangeForAccessTokenWithOidc, {
|
({ item: accessToken } = yield call(api.exchangeForAccessTokenWithOidc, {
|
||||||
|
|||||||
@@ -77,6 +77,7 @@ services:
|
|||||||
# - OIDC_IGNORE_USERNAME=true
|
# - OIDC_IGNORE_USERNAME=true
|
||||||
# - OIDC_IGNORE_ROLES=true
|
# - OIDC_IGNORE_ROLES=true
|
||||||
# - OIDC_ENFORCED=true
|
# - OIDC_ENFORCED=true
|
||||||
|
# - OIDC_DEBUG=true
|
||||||
|
|
||||||
# Email Notifications (https://nodemailer.com/smtp/)
|
# Email Notifications (https://nodemailer.com/smtp/)
|
||||||
# These values override and disable configuration in the UI if set.
|
# These values override and disable configuration in the UI if set.
|
||||||
|
|||||||
@@ -95,6 +95,7 @@ services:
|
|||||||
# - OIDC_IGNORE_USERNAME=true
|
# - OIDC_IGNORE_USERNAME=true
|
||||||
# - OIDC_IGNORE_ROLES=true
|
# - OIDC_IGNORE_ROLES=true
|
||||||
# - OIDC_ENFORCED=true
|
# - OIDC_ENFORCED=true
|
||||||
|
# - OIDC_DEBUG=true
|
||||||
|
|
||||||
# Email Notifications (https://nodemailer.com/smtp/)
|
# Email Notifications (https://nodemailer.com/smtp/)
|
||||||
# These values override and disable configuration in the UI if set.
|
# These values override and disable configuration in the UI if set.
|
||||||
|
|||||||
@@ -68,6 +68,7 @@ SECRET_KEY=notsecretkey
|
|||||||
# OIDC_IGNORE_USERNAME=true
|
# OIDC_IGNORE_USERNAME=true
|
||||||
# OIDC_IGNORE_ROLES=true
|
# OIDC_IGNORE_ROLES=true
|
||||||
# OIDC_ENFORCED=true
|
# OIDC_ENFORCED=true
|
||||||
|
# OIDC_DEBUG=true
|
||||||
|
|
||||||
# Email Notifications (https://nodemailer.com/smtp/)
|
# Email Notifications (https://nodemailer.com/smtp/)
|
||||||
# These values override and disable configuration in the UI if set.
|
# These values override and disable configuration in the UI if set.
|
||||||
|
|||||||
@@ -0,0 +1,223 @@
|
|||||||
|
/*!
|
||||||
|
* Copyright (c) 2024 PLANKA Software GmbH
|
||||||
|
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
|
||||||
|
*/
|
||||||
|
|
||||||
|
const Errors = {
|
||||||
|
NOT_ENOUGH_RIGHTS: {
|
||||||
|
notEnoughRights: 'Not enough rights',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
inputs: {
|
||||||
|
code: {
|
||||||
|
type: 'string',
|
||||||
|
maxLength: 2048,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
nonce: {
|
||||||
|
type: 'string',
|
||||||
|
maxLength: 1024,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
exits: {
|
||||||
|
notEnoughRights: {
|
||||||
|
responseType: 'forbidden',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
async fn(inputs) {
|
||||||
|
if (!sails.config.custom.oidcDebug) {
|
||||||
|
throw Errors.NOT_ENOUGH_RIGHTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
const logs = ['🔐 Starting OIDC debug flow...', ''];
|
||||||
|
const client = await sails.hooks.oidc.getClient();
|
||||||
|
|
||||||
|
if (!client) {
|
||||||
|
logs.push('❌ OIDC client is not initialized.');
|
||||||
|
logs.push('💡 Hint: Check your OIDC issuer and client configuration.');
|
||||||
|
|
||||||
|
return {
|
||||||
|
item: null,
|
||||||
|
included: {
|
||||||
|
logs,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
let tokenSet;
|
||||||
|
try {
|
||||||
|
logs.push('🔄 Exchanging authorization code...');
|
||||||
|
|
||||||
|
if (sails.config.custom.oidcUseOauthCallback) {
|
||||||
|
tokenSet = await client.oauthCallback(
|
||||||
|
sails.config.custom.oidcRedirectUri,
|
||||||
|
{
|
||||||
|
iss: sails.config.custom.oidcIssuer,
|
||||||
|
code: inputs.code,
|
||||||
|
},
|
||||||
|
{ nonce: inputs.nonce },
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
tokenSet = await client.callback(
|
||||||
|
sails.config.custom.oidcRedirectUri,
|
||||||
|
{
|
||||||
|
iss: sails.config.custom.oidcIssuer,
|
||||||
|
code: inputs.code,
|
||||||
|
},
|
||||||
|
{ nonce: inputs.nonce },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
logs.push('✅ Authorization code exchanged successfully.', '');
|
||||||
|
} catch (error) {
|
||||||
|
logs.push('❌ Failed to exchange authorization code.');
|
||||||
|
logs.push(`💬 Reason: ${error.message || error.toString()}`);
|
||||||
|
logs.push('💡 Hint: Check redirect URI, client secret, and nonce handling.');
|
||||||
|
|
||||||
|
return {
|
||||||
|
item: null,
|
||||||
|
included: {
|
||||||
|
logs,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sails.config.custom.oidcClaimsSource === 'id_token') {
|
||||||
|
logs.push('📥 Extracting claims from ID token...');
|
||||||
|
|
||||||
|
try {
|
||||||
|
claims = tokenSet.claims();
|
||||||
|
logs.push('✅ Claims extracted successfully.', '');
|
||||||
|
} catch (error) {
|
||||||
|
logs.push('❌ Failed to extract user claims.');
|
||||||
|
logs.push(`💬 Reason: ${error.message || error.toString()}`);
|
||||||
|
|
||||||
|
return {
|
||||||
|
item: null,
|
||||||
|
included: {
|
||||||
|
logs,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logs.push('📥 Fetching claims from userinfo endpoint...');
|
||||||
|
|
||||||
|
try {
|
||||||
|
claims = await client.userinfo(tokenSet);
|
||||||
|
logs.push('✅ Claims fetched successfully.', '');
|
||||||
|
} catch (error) {
|
||||||
|
logs.push('❌ Failed to fetch user claims.');
|
||||||
|
|
||||||
|
if (error instanceof SyntaxError && error.message.includes('Unexpected token e in JSON')) {
|
||||||
|
logs.push('💬 Reason: Userinfo response is signed or not JSON.');
|
||||||
|
logs.push(
|
||||||
|
'💡 Hint: Try configuring userinfo signed response algorithm or switch to ID token claims.',
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
logs.push(`💬 Reason: ${error.message || error.toString()}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
item: null,
|
||||||
|
included: {
|
||||||
|
logs,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
logs.push('📦 Raw claims received:', JSON.stringify(claims, null, 2), '');
|
||||||
|
logs.push('🧩 Evaluating claim mappings...', '');
|
||||||
|
|
||||||
|
const mappings = {
|
||||||
|
email: {
|
||||||
|
attribute: sails.config.custom.oidcEmailAttribute,
|
||||||
|
value: _.get(claims, sails.config.custom.oidcEmailAttribute),
|
||||||
|
},
|
||||||
|
name: {
|
||||||
|
attribute: sails.config.custom.oidcNameAttribute,
|
||||||
|
value: _.get(claims, sails.config.custom.oidcNameAttribute),
|
||||||
|
},
|
||||||
|
username: sails.config.custom.oidcIgnoreUsername
|
||||||
|
? undefined
|
||||||
|
: {
|
||||||
|
attribute: sails.config.custom.oidcUsernameAttribute,
|
||||||
|
value: _.get(claims, sails.config.custom.oidcUsernameAttribute),
|
||||||
|
},
|
||||||
|
roles: sails.config.custom.oidcIgnoreRoles
|
||||||
|
? undefined
|
||||||
|
: {
|
||||||
|
attribute: sails.config.custom.oidcRolesAttribute,
|
||||||
|
value: _.get(claims, sails.config.custom.oidcRolesAttribute),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
logs.push('📋 Mapping result:', JSON.stringify(mappings, null, 2), '');
|
||||||
|
|
||||||
|
if (!mappings.email.value) {
|
||||||
|
logs.push('❌ Email not resolved.');
|
||||||
|
logs.push('💡 Hint: Check email attribute mapping.', '');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mappings.name.value) {
|
||||||
|
logs.push('❌ Name not resolved.');
|
||||||
|
logs.push('💡 Hint: Check name attribute mapping.', '');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sails.config.custom.oidcIgnoreUsername) {
|
||||||
|
if (!mappings.username.value) {
|
||||||
|
logs.push('⚠️ Username not resolved.');
|
||||||
|
logs.push('💡 Hint: Check username attribute mapping.', '');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sails.config.custom.oidcIgnoreRoles) {
|
||||||
|
if (!Array.isArray(mappings.roles.value) || mappings.roles.value.length === 0) {
|
||||||
|
logs.push('⚠️ Roles not resolved or empty.');
|
||||||
|
logs.push('💡 Hint: Check roles attribute mapping or IdP role configuration.', '');
|
||||||
|
} else {
|
||||||
|
logs.push('🎭 Resolving user role from OIDC roles...');
|
||||||
|
|
||||||
|
// Use a Set here to avoid quadratic time complexity
|
||||||
|
const claimsRolesSet = new Set(mappings.roles.value);
|
||||||
|
|
||||||
|
const foundRole = [User.Roles.ADMIN, User.Roles.PROJECT_OWNER, User.Roles.BOARD_USER].find(
|
||||||
|
(roleItem) => {
|
||||||
|
const configRoles = sails.config.custom[`oidc${_.upperFirst(roleItem)}Roles`];
|
||||||
|
|
||||||
|
if (configRoles.includes('*')) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return configRoles.some((configRole) => claimsRolesSet.has(configRole));
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
if (foundRole) {
|
||||||
|
logs.push(`✅ Matched user role → ${_.lowerCase(foundRole)}`, '');
|
||||||
|
} else {
|
||||||
|
logs.push('⚠️ No user role matched configured OIDC roles.');
|
||||||
|
logs.push('💡 Hint: Check role matching settings.', '');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mappings.email.value && mappings.name.value) {
|
||||||
|
logs.push('🎉 OIDC debug completed successfully.');
|
||||||
|
} else {
|
||||||
|
logs.push('🛑 OIDC debug detected missing required attributes.');
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
item: null,
|
||||||
|
included: {
|
||||||
|
logs,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
};
|
||||||
@@ -61,9 +61,8 @@ module.exports = {
|
|||||||
return Errors.NOT_AVAILABLE;
|
return Errors.NOT_AVAILABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
const logs = [];
|
const logs = ['📧 Sending test email...'];
|
||||||
try {
|
try {
|
||||||
logs.push('📧 Sending test email...');
|
|
||||||
/* eslint-disable no-underscore-dangle */
|
/* eslint-disable no-underscore-dangle */
|
||||||
const info = await transporter.sendMail({
|
const info = await transporter.sendMail({
|
||||||
to: currentUser.email,
|
to: currentUser.email,
|
||||||
@@ -72,16 +71,16 @@ module.exports = {
|
|||||||
html: this.req.i18n.__('This is a <i>test</i> <b>html</b> <code>message</code>!'),
|
html: this.req.i18n.__('This is a <i>test</i> <b>html</b> <code>message</code>!'),
|
||||||
});
|
});
|
||||||
/* eslint-enable no-underscore-dangle */
|
/* eslint-enable no-underscore-dangle */
|
||||||
logs.push('✅ Email sent successfully!', '');
|
logs.push('✅ Email sent successfully.', '');
|
||||||
|
|
||||||
logs.push(`📬 Message ID: ${info.messageId}`);
|
logs.push(`📬 Message ID: ${info.messageId}`);
|
||||||
if (info.response) {
|
if (info.response) {
|
||||||
logs.push(`📤 Server response: ${info.response.trim()}`);
|
logs.push(`📤 Server response: ${info.response.trim()}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
logs.push('', '🎉 Your configuration is working correctly!');
|
logs.push('', '🎉 Your configuration is working correctly.');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logs.push('❌ Failed to send email!', '');
|
logs.push('❌ Failed to send email.', '');
|
||||||
|
|
||||||
if (error.code) {
|
if (error.code) {
|
||||||
logs.push(`⚠️ Error code: ${error.code}`);
|
logs.push(`⚠️ Error code: ${error.code}`);
|
||||||
|
|||||||
@@ -106,6 +106,7 @@ module.exports = {
|
|||||||
if (configRoles.includes('*')) {
|
if (configRoles.includes('*')) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return configRoles.some((configRole) => claimsRolesSet.has(configRole));
|
return configRoles.some((configRole) => claimsRolesSet.has(configRole));
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -89,11 +89,16 @@ module.exports = function defineOidcHook(sails) {
|
|||||||
authorizationUrlParams.response_mode = sails.config.custom.oidcResponseMode;
|
authorizationUrlParams.response_mode = sails.config.custom.oidcResponseMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
const bootstrap = {
|
||||||
authorizationUrl: instance.authorizationUrl(authorizationUrlParams),
|
authorizationUrl: instance.authorizationUrl(authorizationUrlParams),
|
||||||
endSessionUrl: instance.issuer.end_session_endpoint ? instance.endSessionUrl({}) : null,
|
endSessionUrl: instance.issuer.end_session_endpoint ? instance.endSessionUrl({}) : null,
|
||||||
isEnforced: sails.config.custom.oidcEnforced,
|
isEnforced: sails.config.custom.oidcEnforced,
|
||||||
};
|
};
|
||||||
|
if (sails.config.custom.oidcDebug) {
|
||||||
|
bootstrap.debug = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return bootstrap;
|
||||||
},
|
},
|
||||||
|
|
||||||
isEnabled() {
|
isEnabled() {
|
||||||
|
|||||||
@@ -94,6 +94,7 @@ module.exports.custom = {
|
|||||||
oidcIgnoreUsername: process.env.OIDC_IGNORE_USERNAME === 'true',
|
oidcIgnoreUsername: process.env.OIDC_IGNORE_USERNAME === 'true',
|
||||||
oidcIgnoreRoles: process.env.OIDC_IGNORE_ROLES === 'true',
|
oidcIgnoreRoles: process.env.OIDC_IGNORE_ROLES === 'true',
|
||||||
oidcEnforced: process.env.OIDC_ENFORCED === 'true',
|
oidcEnforced: process.env.OIDC_ENFORCED === 'true',
|
||||||
|
oidcDebug: process.env.OIDC_DEBUG === 'true',
|
||||||
|
|
||||||
// TODO: move client base url to environment variable?
|
// TODO: move client base url to environment variable?
|
||||||
oidcRedirectUri: `${
|
oidcRedirectUri: `${
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ module.exports.policies = {
|
|||||||
'terms/show': true,
|
'terms/show': true,
|
||||||
'access-tokens/create': true,
|
'access-tokens/create': true,
|
||||||
'access-tokens/exchange-with-oidc': true,
|
'access-tokens/exchange-with-oidc': true,
|
||||||
|
'access-tokens/debug-oidc': true,
|
||||||
'access-tokens/accept-terms': true,
|
'access-tokens/accept-terms': true,
|
||||||
'access-tokens/revoke-pending-token': true,
|
'access-tokens/revoke-pending-token': true,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -81,6 +81,7 @@ module.exports.routes = {
|
|||||||
|
|
||||||
'POST /api/access-tokens': 'access-tokens/create',
|
'POST /api/access-tokens': 'access-tokens/create',
|
||||||
'POST /api/access-tokens/exchange-with-oidc': 'access-tokens/exchange-with-oidc',
|
'POST /api/access-tokens/exchange-with-oidc': 'access-tokens/exchange-with-oidc',
|
||||||
|
'POST /api/access-tokens/debug-oidc': 'access-tokens/debug-oidc',
|
||||||
'POST /api/access-tokens/accept-terms': 'access-tokens/accept-terms',
|
'POST /api/access-tokens/accept-terms': 'access-tokens/accept-terms',
|
||||||
'POST /api/access-tokens/revoke-pending-token': 'access-tokens/revoke-pending-token',
|
'POST /api/access-tokens/revoke-pending-token': 'access-tokens/revoke-pending-token',
|
||||||
'DELETE /api/access-tokens/me': 'access-tokens/delete',
|
'DELETE /api/access-tokens/me': 'access-tokens/delete',
|
||||||
|
|||||||
Reference in New Issue
Block a user