Skip to content

Commit 38a5e18

Browse files
apognuChibiBlasphem
authored andcommitted
Implement refresh token for OIDC.
1 parent 34b2b10 commit 38a5e18

File tree

3 files changed

+40
-4
lines changed

3 files changed

+40
-4
lines changed

packages/app-builder/src/services/auth/auth.server.ts

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ import { type SessionService } from './session.server';
5252
import { Tokens } from '@app-builder/routes/oidc+/auth';
5353
import { OIDCStrategy } from 'remix-auth-openid';
5454
import { AppConfigRepository } from '@app-builder/repositories/AppConfigRepository';
55+
import { MarbleOidcStrategy } from './oidc.server';
5556

5657
interface AuthenticatedInfo {
5758
/**
@@ -130,6 +131,7 @@ interface MakeAuthenticationServerServiceArgs {
130131
getMarbleCoreAPIClientWithAuth: GetMarbleCoreAPIClientWithAuth;
131132
getTransfercheckAPIClientWithAuth: GetTransfercheckAPIClientWithAuth;
132133
getFeatureAccessAPIClientWithAuth: GetFeatureAccessAPIClientWithAuth;
134+
getAppConfigRepository: (marbleCoreApiClient: MarbleCoreApi) => AppConfigRepository;
133135
getUserRepository: (marbleCoreApiClient: MarbleCoreApi) => UserRepository;
134136
getInboxRepository: (marbleCoreApiClient: MarbleCoreApi) => InboxRepository;
135137
getEditorRepository: (marbleCoreApiClient: MarbleCoreApi) => EditorRepository;
@@ -166,7 +168,7 @@ interface MakeAuthenticationServerServiceArgs {
166168
authSessionService: SessionService<AuthData, AuthFlashData>;
167169
toastSessionService: SessionService<void, ToastFlashData>;
168170
csrfService: CSRF;
169-
makeOidcService: (configRepository: AppConfigRepository) => Promise<OIDCStrategy<Tokens>>;
171+
makeOidcService: (configRepository: AppConfigRepository) => Promise<MarbleOidcStrategy<Tokens>>;
170172
}
171173

172174
function expectedErrors(error: unknown) {
@@ -177,6 +179,7 @@ export function makeAuthenticationServerService({
177179
getMarbleCoreAPIClientWithAuth,
178180
getTransfercheckAPIClientWithAuth,
179181
getFeatureAccessAPIClientWithAuth,
182+
getAppConfigRepository,
180183
getUserRepository,
181184
getInboxRepository,
182185
getEditorRepository,
@@ -209,6 +212,36 @@ export function makeAuthenticationServerService({
209212
return {
210213
getToken: () => Promise.resolve(marbleAccessToken),
211214
refreshToken: async () => {
215+
const appConfigRepository = getAppConfigRepository(marblecoreApi);
216+
const appConfig = await appConfigRepository.getAppConfig();
217+
218+
if (appConfig.auth.provider == 'oidc') {
219+
const oidc = await makeOidcService(appConfigRepository);
220+
221+
if (request) {
222+
const authSession = await authSessionService.getSession(request);
223+
224+
if (authSession.data.refreshToken) {
225+
const response = await oidc.refreshToken(authSession.data.refreshToken);
226+
227+
const marbleToken = await marblecoreApi.postToken(
228+
{
229+
authorization: `Bearer ${response.idToken()}`,
230+
},
231+
{ baseUrl: getServerEnv('MARBLE_API_URL_SERVER') },
232+
);
233+
234+
authSession.set('authToken', marbleToken);
235+
236+
if (response.hasRefreshToken()) {
237+
authSession.set('refreshToken', response.refreshToken());
238+
}
239+
240+
return marbleToken.access_token;
241+
}
242+
}
243+
}
244+
212245
// We don't handle refresh for now, force a logout when 401 is returned instead
213246
throw redirect(getRoute('/ressources/auth/logout'));
214247
},
@@ -386,10 +419,10 @@ export function makeAuthenticationServerService({
386419
else return null;
387420
}
388421

389-
const tokenService = getTokenService(marbleToken.access_token);
422+
const tokenService = getTokenService(marbleToken.access_token, request);
390423
const marbleCoreApiClient = getMarbleCoreAPIClientWithAuth(tokenService);
391424
const featureAccessApiClient = getFeatureAccessAPIClientWithAuth(
392-
getTokenService(marbleToken.access_token),
425+
getTokenService(marbleToken.access_token, request),
393426
);
394427
const transfercheckAPIClient = getTransfercheckAPIClientWithAuth(tokenService);
395428

packages/app-builder/src/services/auth/oidc.server.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { OAuth2Strategy } from 'remix-auth-oauth2';
55

66
let oidcStrategy: MarbleOidcStrategy<Tokens> | undefined = undefined;
77

8-
class MarbleOidcStrategy<U> extends OAuth2Strategy<U> {
8+
export class MarbleOidcStrategy<U> extends OAuth2Strategy<U> {
99
extraParams: { [key: string]: string } = {};
1010

1111
override authorizationParams(searchParams: URLSearchParams, request: Request) {

packages/marble-api/src/helpers/authorization.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ export function createFetchWithAuthMiddleware<Token>({
2626
const response = await basicFetch(input, { ...init, headers });
2727

2828
if (response.status === 401) {
29+
// TODO: here, we use the new tokens for the current request, but it is
30+
// not persisted in the browser, so we are going to be refreshing
31+
// constantly.
2932
const token = await tokenService.refreshToken();
3033
const { name, value } = getAuthorizationHeader(token);
3134
headers.set(name, value);

0 commit comments

Comments
 (0)