Skip to content

Commit

Permalink
Add direct Wonderwall OBO token refresh
Browse files Browse the repository at this point in the history
  • Loading branch information
cskrov committed Oct 7, 2024
1 parent 0a4224a commit 5f3d7ff
Show file tree
Hide file tree
Showing 9 changed files with 66 additions and 110 deletions.
30 changes: 23 additions & 7 deletions frontend/src/components/smart-editor/tabbed-editors/editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ import { useCanEditDocument } from '@app/components/smart-editor/hooks/use-can-e
import { Content } from '@app/components/smart-editor/tabbed-editors/content';
import { PositionedRight } from '@app/components/smart-editor/tabbed-editors/positioned-right';
import { StickyRight } from '@app/components/smart-editor/tabbed-editors/sticky-right';
import { useRefreshOboToken } from '@app/components/smart-editor/tabbed-editors/use-refresh-obo-token';
import { VersionStatus } from '@app/components/smart-editor/tabbed-editors/version-status';
import { DocumentErrorComponent } from '@app/error-boundary/document-error';
import { ErrorBoundary } from '@app/error-boundary/error-boundary';
import { hasOwn, isObject } from '@app/functions/object';
import { useOppgave } from '@app/hooks/oppgavebehandling/use-oppgave';
import { useSmartEditorSpellCheckLanguage } from '@app/hooks/use-smart-editor-language';
import { PlateEditor } from '@app/plate/plate-editor';
Expand Down Expand Up @@ -109,8 +109,6 @@ const PlateContext = ({ smartDocument, oppgave }: PlateContextProps) => {
const editor = useMyPlateEditorRef(id);
const [isConnected, setIsConnected] = useState(editor.yjs.provider.isConnected);

const oboTokenIsValid = useRefreshOboToken();

// const editor = useMyPlateEditorRef(id);

// useEffect(() => {
Expand Down Expand Up @@ -150,11 +148,29 @@ const PlateContext = ({ smartDocument, oppgave }: PlateContextProps) => {

useEffect(() => {
// Close happens after connect is broken. Safe to reconnect.
const onClose = () => {
const onClose = async () => {
setIsConnected(false);

if (oboTokenIsValid) {
editor.yjs.provider.connect();
try {
const res = await fetch('/oauth2/session', { credentials: 'include' });

if (!res.ok) {
throw new Error(`API responded with error code ${res.status} for /oauth2/session`);
}

const data: unknown = await res.json();

if (
isObject(data) &&
hasOwn(data, 'session') &&
isObject(data.session) &&
hasOwn(data.session, 'active') &&
data.session.active === true
) {
editor.yjs.provider.connect();
}
} catch (err) {
console.error(err);
}
};

Expand All @@ -163,7 +179,7 @@ const PlateContext = ({ smartDocument, oppgave }: PlateContextProps) => {
return () => {
editor.yjs.provider.off('close', onClose);
};
}, [editor.yjs.provider, oboTokenIsValid]);
}, [editor.yjs.provider]);

useEffect(() => {
// Disconnect happens before close. Too early to reconnect.
Expand Down

This file was deleted.

6 changes: 6 additions & 0 deletions frontend/src/functions/object.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/** Checks if the given object has the given property. */
export const hasOwn = <T extends object, K extends PropertyKey>(obj: T, key: K): obj is T & Record<K, unknown> =>
Object.hasOwn(obj, key);

export const isObject = (value: unknown): value is Record<string, unknown> =>
value !== null && typeof value === 'object';
1 change: 1 addition & 0 deletions frontend/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export default defineConfig({
'/nytt-dokument': PROXY,
'/vedleggsoversikt': PROXY,
'/version': PROXY,
'/oauth': PROXY,
},
},
});
2 changes: 1 addition & 1 deletion server/src/auth/cache/cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ class OboSimpleCache {

public getCached = this.get;

public set(key: string, token: string, expiresAt: number): void {
public async set(key: string, token: string, expiresAt: number): Promise<void> {
this.#oboMemoryCache.set(key, token, expiresAt);
}

Expand Down
2 changes: 1 addition & 1 deletion server/src/auth/on-behalf-of.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ export const refreshOnBehalfOfAccessToken = async (
}

if (typeof expires_at === 'number') {
oboCache.set(cacheKey, obo_access_token, expires_at);
await oboCache.set(cacheKey, obo_access_token, expires_at);
}

return obo_access_token;
Expand Down
33 changes: 31 additions & 2 deletions server/src/plugins/crdt/collaboration-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,39 @@ export const collaborationServer = Server.configure({
}

const { navIdent } = context;
const oboAccessToken = await oboCache.get(getCacheKey(navIdent, ApiClientEnum.KABAL_API));
let oboAccessToken = await oboCache.get(getCacheKey(navIdent, ApiClientEnum.KABAL_API));

if (oboAccessToken === null && context.cookie !== undefined) {
logContext('Trying to refresh OBO token', context, 'debug');

try {
// Refresh OBO token directly through Wonderwall.
const res = await fetch('http://localhost:7564/collaboration/refresh-obo-access-token', {
method: 'GET',
headers: {
Cookie: context.cookie,
},
});

if (res.ok) {
oboAccessToken = await oboCache.get(getCacheKey(navIdent, ApiClientEnum.KABAL_API));
logContext('OBO token refreshed', context, 'debug');
} else {
throw new Error(`Wonderwall responded with status code ${res.status}`);
}
} catch (err) {
logContext(`Failed to refresh OBO token. ${err instanceof Error ? err : 'Unknown error.'}`, context, 'warn');
throw getCloseEvent('MISSING_OBO_TOKEN', 4403);
}
}

if (oboAccessToken === null) {
logContext('No OBO token', context, 'warn');
if (context.cookie === undefined) {
logContext('Missing session cookie', context, 'warn');
throw getCloseEvent('MISSING_COOKIE', 4403);
}

logContext('Missing OBO token', context, 'warn');
throw getCloseEvent('MISSING_OBO_TOKEN', 4403);
}

Expand Down
1 change: 1 addition & 0 deletions server/src/plugins/crdt/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export interface ConnectionContext {
readonly tab_id?: string;
readonly client_version?: string;
readonly navIdent: string;
readonly cookie: string | undefined;
}

export const isConnectionContext = (data: unknown): data is ConnectionContext =>
Expand Down
3 changes: 2 additions & 1 deletion server/src/plugins/crdt/crdt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ export const crdtPlugin = fastifyPlugin(

logReq('Handing over connection to HocusPocus', req, { behandlingId, dokumentId });

const { navIdent, trace_id, span_id, tab_id, client_version } = req;
const { navIdent, trace_id, span_id, tab_id, client_version, headers } = req;

const context: ConnectionContext = {
behandlingId,
Expand All @@ -192,6 +192,7 @@ export const crdtPlugin = fastifyPlugin(
tab_id,
client_version,
navIdent,
cookie: headers.cookie,
};

collaborationServer.handleConnection(webSocket, req.raw, context);
Expand Down

0 comments on commit 5f3d7ff

Please sign in to comment.