Skip to content

Commit

Permalink
use auth-client fetch
Browse files Browse the repository at this point in the history
  • Loading branch information
a-type committed Jun 14, 2024
1 parent 86c7bdf commit 4da9e20
Show file tree
Hide file tree
Showing 7 changed files with 69 additions and 132 deletions.
2 changes: 1 addition & 1 deletion apps/gnocchi/verdant/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"react": "18.3.1"
},
"dependencies": {
"@0no-co/graphqlsp": "^1.3.4",
"@0no-co/graphqlsp": "1.12.8",
"@biscuits/client": "workspace:*",
"@verdant-web/cli": "^4.4.0",
"@verdant-web/common": "2.3.1",
Expand Down
3 changes: 2 additions & 1 deletion packages/client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@
},
"type": "module",
"dependencies": {
"@0no-co/graphqlsp": "^1.3.4",
"@0no-co/graphqlsp": "1.12.8",
"@a-type/auth-client": "1.0.6",
"@apollo/client": "^3.9.9",
"@biscuits/apps": "workspace:*",
"@biscuits/error": "workspace:*",
Expand Down
105 changes: 16 additions & 89 deletions packages/client/src/fetch.ts
Original file line number Diff line number Diff line change
@@ -1,98 +1,25 @@
import { BiscuitsError } from '@biscuits/error';
import { CONFIG } from './index.js';

// wrap fetch to automatically redirect to /join on 401
export const fetch: typeof window.fetch = async (input: any, init: any) => {
// ensure cookies are always sent
if (typeof input === 'object') {
input.credentials = 'include';
}
if (typeof init === 'object') {
init.credentials = 'include';
}

const requestUrlString = typeof input === 'string' ? input : input.url;
const requestUrlOrigin = new URL(requestUrlString).origin;

const response = await window.fetch.bind(window)(input, init);

const { body, clone } = await peekAtResponseBody(response);
const biscuitsError = BiscuitsError.readResponseBody(body);
if (biscuitsError) {
console.error('Biscuits Error', biscuitsError);
if (biscuitsError.code === BiscuitsError.Code.SessionExpired) {
// if the session expired, we need to refresh it
const refreshSuccess = await refreshSession(requestUrlOrigin);
if (refreshSuccess) {
// retry the original request
return fetch(input, init);
} else {
// failed to refresh the session - the user needs
// to log in again
}
import { API_ORIGIN, HOME_ORIGIN } from './config.js';
import { createFetch } from '@a-type/auth-client';

export { refreshSession } from '@a-type/auth-client';

export const fetch = createFetch({
readBody: true,
refreshSessionEndpoint: `${API_ORIGIN}/auth/refresh`,
isSessionExpired: (res, body) => {
const biscuitsError = BiscuitsError.readResponseBody(body);
if (biscuitsError) {
console.error('Biscuits Error', biscuitsError);
return biscuitsError.code === BiscuitsError.Code.SessionExpired;
}
}
return clone;
};

export async function refreshSession(apiOrigin: string) {
if (!refreshPromise) {
refreshPromise = refreshSessionInternal(apiOrigin);
refreshPromise.finally(() => {
refreshPromise = null;
});
}
return refreshPromise;
}

let refreshPromise: Promise<boolean> | null = null;
async function refreshSessionInternal(apiOrigin: string) {
try {
const response = await fetch(`${apiOrigin}/auth/refresh`, {
method: 'POST',
});
if (response.ok) {
const body = await response.json();
if (body.ok) {
console.info('session refreshed');
} else {
console.error('session refresh failed', body);
}
} else if (response.status === 401 || response.status === 403) {
console.error('session refresh failed', response.status);
} else {
console.error('session refresh failed', response.status);
}
return response.ok;
} catch (e) {
console.error(e);
return false;
}
}

async function peekAtResponseBody(response: Response): Promise<{
body: any;
clone: Response;
}> {
const clone = response.clone();
try {
const body = await response.json();
return {
body,
clone,
};
} catch (e) {
console.error(e);
}
return {
body: null,
clone,
};
}
},
});

export function login() {
window.location.href =
CONFIG.HOME_ORIGIN +
HOME_ORIGIN +
'/login' +
'?returnTo=' +
encodeURIComponent(window.location.href);
Expand Down
83 changes: 46 additions & 37 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 4da9e20

Please sign in to comment.