1
0
Fork 0
mirror of https://github.com/plankanban/planka.git synced 2025-07-19 21:29:43 +02:00

ref: Refactoring

This commit is contained in:
Maksim Eltyshev 2023-10-19 16:05:34 +02:00
parent 9011ee61da
commit 0fab6075bd
23 changed files with 96 additions and 91 deletions

View file

@ -28,20 +28,20 @@ authenticate.failure = (error) => ({
}, },
}); });
const authenticateWithOidc = () => ({ const authenticateUsingOidc = () => ({
type: ActionTypes.WITH_OIDC_AUTHENTICATE, type: ActionTypes.USING_OIDC_AUTHENTICATE,
payload: {}, payload: {},
}); });
authenticateWithOidc.success = (accessToken) => ({ authenticateUsingOidc.success = (accessToken) => ({
type: ActionTypes.WITH_OIDC_AUTHENTICATE__SUCCESS, type: ActionTypes.USING_OIDC_AUTHENTICATE__SUCCESS,
payload: { payload: {
accessToken, accessToken,
}, },
}); });
authenticateWithOidc.failure = (error) => ({ authenticateUsingOidc.failure = (error) => ({
type: ActionTypes.WITH_OIDC_AUTHENTICATE__FAILURE, type: ActionTypes.USING_OIDC_AUTHENTICATE__FAILURE,
payload: { payload: {
error, error,
}, },
@ -55,6 +55,6 @@ const clearAuthenticateError = () => ({
export default { export default {
initializeLogin, initializeLogin,
authenticate, authenticate,
authenticateWithOidc, authenticateUsingOidc,
clearAuthenticateError, clearAuthenticateError,
}; };

View file

@ -5,14 +5,14 @@ import socket from './socket';
const createAccessToken = (data, headers) => http.post('/access-tokens', data, headers); const createAccessToken = (data, headers) => http.post('/access-tokens', data, headers);
const exchangeToAccessToken = (data, headers) => const exchangeForAccessTokenUsingOidc = (data, headers) =>
http.post('/access-tokens/exchange', data, headers); http.post('/access-tokens/exchange-using-oidc', data, headers);
const deleteCurrentAccessToken = (headers) => const deleteCurrentAccessToken = (headers) =>
socket.delete('/access-tokens/me', undefined, headers); socket.delete('/access-tokens/me', undefined, headers);
export default { export default {
createAccessToken, createAccessToken,
exchangeToAccessToken, exchangeForAccessTokenUsingOidc,
deleteCurrentAccessToken, deleteCurrentAccessToken,
}; };

View file

@ -65,11 +65,11 @@ const Login = React.memo(
({ ({
defaultData, defaultData,
isSubmitting, isSubmitting,
isSubmittingWithOidc, isSubmittingUsingOidc,
error, error,
withOidc, withOidc,
onAuthenticate, onAuthenticate,
onAuthenticateWithOidc, onAuthenticateUsingOidc,
onMessageDismiss, onMessageDismiss,
}) => { }) => {
const [t] = useTranslation(); const [t] = useTranslation();
@ -192,15 +192,15 @@ const Login = React.memo(
content={t('action.logIn')} content={t('action.logIn')}
floated="right" floated="right"
loading={isSubmitting} loading={isSubmitting}
disabled={isSubmitting || isSubmittingWithOidc} disabled={isSubmitting || isSubmittingUsingOidc}
/> />
</Form> </Form>
{withOidc && ( {withOidc && (
<Button <Button
type="button" type="button"
loading={isSubmittingWithOidc} loading={isSubmittingUsingOidc}
disabled={isSubmitting || isSubmittingWithOidc} disabled={isSubmitting || isSubmittingUsingOidc}
onClick={onAuthenticateWithOidc} onClick={onAuthenticateUsingOidc}
> >
{t('action.logInWithSSO')} {t('action.logInWithSSO')}
</Button> </Button>
@ -239,11 +239,11 @@ Login.propTypes = {
defaultData: PropTypes.object.isRequired, defaultData: PropTypes.object.isRequired,
/* eslint-enable react/forbid-prop-types */ /* eslint-enable react/forbid-prop-types */
isSubmitting: PropTypes.bool.isRequired, isSubmitting: PropTypes.bool.isRequired,
isSubmittingWithOidc: PropTypes.bool.isRequired, isSubmittingUsingOidc: PropTypes.bool.isRequired,
error: PropTypes.object, // eslint-disable-line react/forbid-prop-types error: PropTypes.object, // eslint-disable-line react/forbid-prop-types
withOidc: PropTypes.bool.isRequired, withOidc: PropTypes.bool.isRequired,
onAuthenticate: PropTypes.func.isRequired, onAuthenticate: PropTypes.func.isRequired,
onAuthenticateWithOidc: PropTypes.func.isRequired, onAuthenticateUsingOidc: PropTypes.func.isRequired,
onMessageDismiss: PropTypes.func.isRequired, onMessageDismiss: PropTypes.func.isRequired,
}; };

View file

@ -16,9 +16,9 @@ export default {
AUTHENTICATE: 'AUTHENTICATE', AUTHENTICATE: 'AUTHENTICATE',
AUTHENTICATE__SUCCESS: 'AUTHENTICATE__SUCCESS', AUTHENTICATE__SUCCESS: 'AUTHENTICATE__SUCCESS',
AUTHENTICATE__FAILURE: 'AUTHENTICATE__FAILURE', AUTHENTICATE__FAILURE: 'AUTHENTICATE__FAILURE',
WITH_OIDC_AUTHENTICATE: 'WITH_OIDC_AUTHENTICATE', USING_OIDC_AUTHENTICATE: 'USING_OIDC_AUTHENTICATE',
WITH_OIDC_AUTHENTICATE__SUCCESS: 'WITH_OIDC_AUTHENTICATE__SUCCESS', USING_OIDC_AUTHENTICATE__SUCCESS: 'USING_OIDC_AUTHENTICATE__SUCCESS',
WITH_OIDC_AUTHENTICATE__FAILURE: 'WITH_OIDC_AUTHENTICATE__FAILURE', USING_OIDC_AUTHENTICATE__FAILURE: 'USING_OIDC_AUTHENTICATE__FAILURE',
AUTHENTICATE_ERROR_CLEAR: 'AUTHENTICATE_ERROR_CLEAR', AUTHENTICATE_ERROR_CLEAR: 'AUTHENTICATE_ERROR_CLEAR',
/* Core */ /* Core */

View file

@ -11,7 +11,7 @@ export default {
/* Login */ /* Login */
AUTHENTICATE: `${PREFIX}/AUTHENTICATE`, AUTHENTICATE: `${PREFIX}/AUTHENTICATE`,
WITH_OIDC_AUTHENTICATE: `${PREFIX}/WITH_OIDC_AUTHENTICATE`, USING_OIDC_AUTHENTICATE: `${PREFIX}/USING_OIDC_AUTHENTICATE`,
AUTHENTICATE_ERROR_CLEAR: `${PREFIX}/AUTHENTICATE_ERROR_CLEAR`, AUTHENTICATE_ERROR_CLEAR: `${PREFIX}/AUTHENTICATE_ERROR_CLEAR`,
/* Core */ /* Core */

View file

@ -10,14 +10,14 @@ const mapStateToProps = (state) => {
const { const {
ui: { ui: {
authenticateForm: { data: defaultData, isSubmitting, isSubmittingWithOidc, error }, authenticateForm: { data: defaultData, isSubmitting, isSubmittingUsingOidc, error },
}, },
} = state; } = state;
return { return {
defaultData, defaultData,
isSubmitting, isSubmitting,
isSubmittingWithOidc, isSubmittingUsingOidc,
error, error,
withOidc: !!oidcConfig, withOidc: !!oidcConfig,
}; };
@ -27,7 +27,7 @@ const mapDispatchToProps = (dispatch) =>
bindActionCreators( bindActionCreators(
{ {
onAuthenticate: entryActions.authenticate, onAuthenticate: entryActions.authenticate,
onAuthenticateWithOidc: entryActions.authenticateWithOidc, onAuthenticateUsingOidc: entryActions.authenticateUsingOidc,
onMessageDismiss: entryActions.clearAuthenticateError, onMessageDismiss: entryActions.clearAuthenticateError,
}, },
dispatch, dispatch,

View file

@ -7,8 +7,8 @@ const authenticate = (data) => ({
}, },
}); });
const authenticateWithOidc = () => ({ const authenticateUsingOidc = () => ({
type: EntryActionTypes.WITH_OIDC_AUTHENTICATE, type: EntryActionTypes.USING_OIDC_AUTHENTICATE,
payload: {}, payload: {},
}); });
@ -19,6 +19,6 @@ const clearAuthenticateError = () => ({
export default { export default {
authenticate, authenticate,
authenticateWithOidc, authenticateUsingOidc,
clearAuthenticateError, clearAuthenticateError,
}; };

View file

@ -10,7 +10,7 @@ const initialState = {
export default (state = initialState, { type, payload }) => { export default (state = initialState, { type, payload }) => {
switch (type) { switch (type) {
case ActionTypes.AUTHENTICATE__SUCCESS: case ActionTypes.AUTHENTICATE__SUCCESS:
case ActionTypes.WITH_OIDC_AUTHENTICATE__SUCCESS: case ActionTypes.USING_OIDC_AUTHENTICATE__SUCCESS:
return { return {
...state, ...state,
accessToken: payload.accessToken, accessToken: payload.accessToken,

View file

@ -15,7 +15,7 @@ export default (state = initialState, { type, payload }) => {
config: payload.config, config: payload.config,
}; };
case ActionTypes.AUTHENTICATE__SUCCESS: case ActionTypes.AUTHENTICATE__SUCCESS:
case ActionTypes.WITH_OIDC_AUTHENTICATE__SUCCESS: case ActionTypes.USING_OIDC_AUTHENTICATE__SUCCESS:
return { return {
...state, ...state,
isInitializing: true, isInitializing: true,

View file

@ -9,7 +9,7 @@ const initialState = {
password: '', password: '',
}, },
isSubmitting: false, isSubmitting: false,
isSubmittingWithOidc: false, isSubmittingUsingOidc: false,
error: null, error: null,
}; };
@ -20,7 +20,7 @@ export default (state = initialState, { type, payload }) => {
if (payload.location.pathname === Paths.OIDC_CALLBACK) { if (payload.location.pathname === Paths.OIDC_CALLBACK) {
return { return {
...state, ...state,
isSubmittingWithOidc: true, isSubmittingUsingOidc: true,
}; };
} }
@ -35,7 +35,7 @@ export default (state = initialState, { type, payload }) => {
isSubmitting: true, isSubmitting: true,
}; };
case ActionTypes.AUTHENTICATE__SUCCESS: case ActionTypes.AUTHENTICATE__SUCCESS:
case ActionTypes.WITH_OIDC_AUTHENTICATE__SUCCESS: case ActionTypes.USING_OIDC_AUTHENTICATE__SUCCESS:
return initialState; return initialState;
case ActionTypes.AUTHENTICATE__FAILURE: case ActionTypes.AUTHENTICATE__FAILURE:
return { return {
@ -43,10 +43,10 @@ export default (state = initialState, { type, payload }) => {
isSubmitting: false, isSubmitting: false,
error: payload.error, error: payload.error,
}; };
case ActionTypes.WITH_OIDC_AUTHENTICATE__FAILURE: case ActionTypes.USING_OIDC_AUTHENTICATE__FAILURE:
return { return {
...state, ...state,
isSubmittingWithOidc: false, isSubmittingUsingOidc: false,
error: payload.error, error: payload.error,
}; };
case ActionTypes.AUTHENTICATE_ERROR_CLEAR: case ActionTypes.AUTHENTICATE_ERROR_CLEAR:

View file

@ -1,7 +1,8 @@
import { all, apply, fork, take } from 'redux-saga/effects'; import { all, apply, fork, select, take } from 'redux-saga/effects';
import watchers from './watchers'; import watchers from './watchers';
import services from './services'; import services from './services';
import selectors from '../../selectors';
import { socket } from '../../api'; import { socket } from '../../api';
import ActionTypes from '../../constants/ActionTypes'; import ActionTypes from '../../constants/ActionTypes';
import Paths from '../../constants/Paths'; import Paths from '../../constants/Paths';
@ -14,5 +15,12 @@ export default function* coreSaga() {
yield take(ActionTypes.LOGOUT); yield take(ActionTypes.LOGOUT);
window.location.href = Paths.LOGIN; const oidcConfig = yield select(selectors.selectOidcConfig);
if (oidcConfig && oidcConfig.endSessionUrl !== null) {
// Redirect the user to the IDP to log out.
window.location.href = oidcConfig.endSessionUrl;
} else {
window.location.href = Paths.LOGIN;
}
} }

View file

@ -83,15 +83,7 @@ export function* logout(invalidateAccessToken = true) {
} catch (error) {} // eslint-disable-line no-empty } catch (error) {} // eslint-disable-line no-empty
} }
const oidcConfig = yield select(selectors.selectOidcConfig);
yield put(actions.logout()); yield put(actions.logout());
if (oidcConfig && oidcConfig.endSessionUrl !== null) {
// Redirect the user to the IDP to log out.
window.location.replace(oidcConfig.endSessionUrl);
}
yield take(); yield take();
} }

View file

@ -9,7 +9,7 @@ export default function* loginSaga() {
yield fork(services.initializeLogin); yield fork(services.initializeLogin);
yield take([ActionTypes.AUTHENTICATE__SUCCESS, ActionTypes.WITH_OIDC_AUTHENTICATE__SUCCESS]); yield take([ActionTypes.AUTHENTICATE__SUCCESS, ActionTypes.USING_OIDC_AUTHENTICATE__SUCCESS]);
yield cancel(watcherTasks); yield cancel(watcherTasks);
yield call(services.goToRoot); yield call(services.goToRoot);

View file

@ -29,19 +29,22 @@ export function* authenticate(data) {
yield put(actions.authenticate.success(accessToken)); yield put(actions.authenticate.success(accessToken));
} }
export function* authenticateWithOidc() { export function* authenticateUsingOidc() {
const oidcConfig = yield select(selectors.selectOidcConfig); const oidcConfig = yield select(selectors.selectOidcConfig);
const nonce = nanoid(); const nonce = nanoid();
window.sessionStorage.setItem('oidc-nonce', nonce); window.sessionStorage.setItem('oidc-nonce', nonce);
window.location.replace(`${oidcConfig.authorizationUrl}&nonce=${encodeURIComponent(nonce)}`); window.location.href = `${oidcConfig.authorizationUrl}&nonce=${encodeURIComponent(nonce)}`;
} }
export function* authenticateWithOidcCallback() { export function* authenticateUsingOidcCallback() {
const params = new URLSearchParams(window.location.hash.substring(1)); const params = new URLSearchParams(window.location.hash.substring(1));
yield put(replace(Paths.LOGIN));
if (params.get('error') !== null) { if (params.get('error') !== null) {
yield put( yield put(
actions.authenticateWithOidc.failure( actions.authenticateUsingOidc.failure(
new Error( new Error(
`OIDC Authorization error: ${params.get('error')}: ${params.get('error_description')}`, `OIDC Authorization error: ${params.get('error')}: ${params.get('error_description')}`,
), ),
@ -53,7 +56,7 @@ export function* authenticateWithOidcCallback() {
const nonce = window.sessionStorage.getItem('oidc-nonce'); const nonce = window.sessionStorage.getItem('oidc-nonce');
if (nonce === null) { if (nonce === null) {
yield put( yield put(
actions.authenticateWithOidc.failure( actions.authenticateUsingOidc.failure(
new Error('Unable to process OIDC response: no nonce issued'), new Error('Unable to process OIDC response: no nonce issued'),
), ),
); );
@ -63,29 +66,27 @@ export function* authenticateWithOidcCallback() {
const code = params.get('code'); const code = params.get('code');
if (code === null) { if (code === null) {
yield put( yield put(
actions.authenticateWithOidc.failure(new Error('Invalid OIDC response: no code parameter')), actions.authenticateUsingOidc.failure(new Error('Invalid OIDC response: no code parameter')),
); );
return; return;
} }
window.sessionStorage.removeItem('oidc-nonce'); window.sessionStorage.removeItem('oidc-nonce');
yield put(replace(Paths.LOGIN));
if (code !== null) { if (code !== null) {
let accessToken; let accessToken;
try { try {
({ item: accessToken } = yield call(api.exchangeToAccessToken, { ({ item: accessToken } = yield call(api.exchangeForAccessTokenUsingOidc, {
code, code,
nonce, nonce,
})); }));
} catch (error) { } catch (error) {
yield put(actions.authenticateWithOidc.failure(error)); yield put(actions.authenticateUsingOidc.failure(error));
return; return;
} }
yield call(setAccessToken, accessToken); yield call(setAccessToken, accessToken);
yield put(actions.authenticateWithOidc.success(accessToken)); yield put(actions.authenticateUsingOidc.success(accessToken));
} }
} }
@ -96,7 +97,7 @@ export function* clearAuthenticateError() {
export default { export default {
initializeLogin, initializeLogin,
authenticate, authenticate,
authenticateWithOidc, authenticateUsingOidc,
authenticateWithOidcCallback, authenticateUsingOidcCallback,
clearAuthenticateError, clearAuthenticateError,
}; };

View file

@ -1,7 +1,7 @@
import { call, put, select, take } from 'redux-saga/effects'; import { call, put, select, take } from 'redux-saga/effects';
import { push } from '../../../lib/redux-router'; import { push } from '../../../lib/redux-router';
import { authenticateWithOidcCallback } from './login'; import { authenticateUsingOidcCallback } from './login';
import selectors from '../../../selectors'; import selectors from '../../../selectors';
import ActionTypes from '../../../constants/ActionTypes'; import ActionTypes from '../../../constants/ActionTypes';
import Paths from '../../../constants/Paths'; import Paths from '../../../constants/Paths';
@ -36,9 +36,7 @@ export function* handleLocationChange() {
yield take(ActionTypes.LOGIN_INITIALIZE); yield take(ActionTypes.LOGIN_INITIALIZE);
} }
// TODO: check if OIDC is enabled yield call(authenticateUsingOidcCallback);
yield call(authenticateWithOidcCallback);
break; break;
} }

View file

@ -8,7 +8,7 @@ export default function* loginWatchers() {
takeEvery(EntryActionTypes.AUTHENTICATE, ({ payload: { data } }) => takeEvery(EntryActionTypes.AUTHENTICATE, ({ payload: { data } }) =>
services.authenticate(data), services.authenticate(data),
), ),
takeEvery(EntryActionTypes.WITH_OIDC_AUTHENTICATE, () => services.authenticateWithOidc()), takeEvery(EntryActionTypes.USING_OIDC_AUTHENTICATE, () => services.authenticateUsingOidc()),
takeEvery(EntryActionTypes.AUTHENTICATE_ERROR_CLEAR, () => services.clearAuthenticateError()), takeEvery(EntryActionTypes.AUTHENTICATE_ERROR_CLEAR, () => services.clearAuthenticateError()),
]); ]);
} }

View file

@ -1,8 +1,8 @@
const { getRemoteAddress } = require('../../../utils/remoteAddress'); const { getRemoteAddress } = require('../../../utils/remoteAddress');
const Errors = { const Errors = {
INVALID_TOKEN: { INVALID_CODE_OR_NONCE: {
invalidToken: 'Invalid token', invalidCodeOrNonce: 'Invalid code or nonce',
}, },
EMAIL_ALREADY_IN_USE: { EMAIL_ALREADY_IN_USE: {
emailAlreadyInUse: 'Email already in use', emailAlreadyInUse: 'Email already in use',
@ -28,7 +28,7 @@ module.exports = {
}, },
exits: { exits: {
invalidToken: { invalidCodeOrNonce: {
responseType: 'unauthorized', responseType: 'unauthorized',
}, },
emailAlreadyInUse: { emailAlreadyInUse: {
@ -46,10 +46,10 @@ module.exports = {
const remoteAddress = getRemoteAddress(this.req); const remoteAddress = getRemoteAddress(this.req);
const user = await sails.helpers.users const user = await sails.helpers.users
.getOrCreateOneByOidcToken(inputs.code, inputs.nonce) .getOrCreateOneUsingOidc(inputs.code, inputs.nonce)
.intercept('invalidToken', () => { .intercept('invalidCodeOrNonce', () => {
sails.log.warn(`Invalid token! (IP: ${remoteAddress})`); sails.log.warn(`Invalid code or nonce! (IP: ${remoteAddress})`);
return Errors.INVALID_TOKEN; return Errors.INVALID_CODE_OR_NONCE;
}) })
.intercept('emailAlreadyInUse', () => Errors.EMAIL_ALREADY_IN_USE) .intercept('emailAlreadyInUse', () => Errors.EMAIL_ALREADY_IN_USE)
.intercept('usernameAlreadyInUse', () => Errors.USERNAME_ALREADY_IN_USE) .intercept('usernameAlreadyInUse', () => Errors.USERNAME_ALREADY_IN_USE)

View file

@ -1,20 +1,21 @@
module.exports = { module.exports = {
fn() { fn() {
const oidcClient = sails.hooks.oidc.isActive() ? sails.hooks.oidc.getClient() : null; let oidc = null;
if (sails.hooks.oidc.isActive()) {
const oidcClient = sails.hooks.oidc.getClient();
oidc = {
authorizationUrl: oidcClient.authorizationUrl({
scope: sails.config.custom.oidcScopes,
response_mode: 'fragment',
}),
endSessionUrl: oidcClient.issuer.end_session_endpoint ? oidcClient.endSessionUrl({}) : null,
};
}
return { return {
item: { item: {
oidc: oidc,
sails.config.custom.oidcIssuer !== ''
? {
authorizationUrl: oidcClient.authorizationUrl({
scope: sails.config.custom.oidcScopes,
response_mode: 'fragment',
}),
endSessionUrl: oidcClient.issuer.end_session_endpoint
? oidcClient.endSessionUrl({})
: null,
}
: null,
}, },
}; };
}, },

View file

@ -11,7 +11,7 @@ module.exports = {
}, },
exits: { exits: {
invalidToken: {}, invalidCodeOrNonce: {},
missingValues: {}, missingValues: {},
emailAlreadyInUse: {}, emailAlreadyInUse: {},
usernameAlreadyInUse: {}, usernameAlreadyInUse: {},
@ -23,14 +23,14 @@ module.exports = {
let userInfo; let userInfo;
try { try {
const tokenSet = await client.callback( const tokenSet = await client.callback(
`${sails.config.custom.baseUrl}/oidc-callback`, sails.config.custom.oidcRedirectUri,
{ code: inputs.code }, { code: inputs.code },
{ nonce: inputs.nonce }, { nonce: inputs.nonce },
); );
userInfo = await client.userinfo(tokenSet); userInfo = await client.userinfo(tokenSet);
} catch (e) { } catch (e) {
sails.log.warn(`Error while exchanging OIDC code: ${e}`); sails.log.warn(`Error while exchanging OIDC code: ${e}`);
throw 'invalidToken'; throw 'invalidCodeOrNonce';
} }
if (!userInfo.email || !userInfo.name) { if (!userInfo.email || !userInfo.name) {
@ -73,7 +73,7 @@ module.exports = {
} else { } else {
// If no IDP/User mapping exists, search for the user by email. // If no IDP/User mapping exists, search for the user by email.
user = await sails.helpers.users.getOne({ user = await sails.helpers.users.getOne({
email: values.email, email: values.email.toLowerCase(),
}); });
// Otherwise, create a new user. // Otherwise, create a new user.

View file

@ -15,7 +15,7 @@ module.exports = function oidcServiceHook(sails) {
client = new issuer.Client({ client = new issuer.Client({
client_id: sails.config.custom.oidcClientId, client_id: sails.config.custom.oidcClientId,
client_secret: sails.config.custom.oidcClientSecret, client_secret: sails.config.custom.oidcClientSecret,
redirect_uris: [`${sails.config.custom.baseUrl}/oidc-callback`], redirect_uris: [sails.config.custom.oidcRedirectUri],
response_types: ['code'], response_types: ['code'],
}); });
sails.log.info('OIDC hook has been loaded successfully'); sails.log.info('OIDC hook has been loaded successfully');

View file

@ -39,4 +39,9 @@ module.exports.custom = {
oidcScopes: process.env.OIDC_SCOPES || 'openid email profile', oidcScopes: process.env.OIDC_SCOPES || 'openid email profile',
oidcAdminRoles: process.env.OIDC_ADMIN_ROLES ? process.env.OIDC_ADMIN_ROLES.split(',') : [], oidcAdminRoles: process.env.OIDC_ADMIN_ROLES ? process.env.OIDC_ADMIN_ROLES.split(',') : [],
oidcRolesAttribute: process.env.OIDC_ROLES_ATTRIBUTE || 'groups', oidcRolesAttribute: process.env.OIDC_ROLES_ATTRIBUTE || 'groups',
// TODO: move client base url to environment variable?
oidcRedirectUri: `${
sails.config.environment === 'production' ? process.env.BASE_URL : 'http://localhost:3000'
}/oidc-callback`,
}; };

View file

@ -25,5 +25,5 @@ module.exports.policies = {
'show-config': true, 'show-config': true,
'access-tokens/create': true, 'access-tokens/create': true,
'access-tokens/exchange': true, 'access-tokens/exchange-using-oidc': true,
}; };

View file

@ -12,7 +12,7 @@ module.exports.routes = {
'GET /api/config': 'show-config', 'GET /api/config': 'show-config',
'POST /api/access-tokens': 'access-tokens/create', 'POST /api/access-tokens': 'access-tokens/create',
'POST /api/access-tokens/exchange': 'access-tokens/exchange', 'POST /api/access-tokens/exchange-using-oidc': 'access-tokens/exchange-using-oidc',
'DELETE /api/access-tokens/me': 'access-tokens/delete', 'DELETE /api/access-tokens/me': 'access-tokens/delete',
'GET /api/users': 'users/index', 'GET /api/users': 'users/index',