Compare commits
1 Commits
feature/FA
...
feature/FA
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d109db2155 |
14
fictionarchive-web-astro/package-lock.json
generated
14
fictionarchive-web-astro/package-lock.json
generated
@@ -12,6 +12,7 @@
|
|||||||
"@astrojs/svelte": "^7.2.2",
|
"@astrojs/svelte": "^7.2.2",
|
||||||
"@tailwindcss/vite": "^4.1.17",
|
"@tailwindcss/vite": "^4.1.17",
|
||||||
"@urql/core": "^6.0.1",
|
"@urql/core": "^6.0.1",
|
||||||
|
"@urql/exchange-auth": "^3.0.0",
|
||||||
"@urql/svelte": "^5.0.0",
|
"@urql/svelte": "^5.0.0",
|
||||||
"astro": "^5.16.2",
|
"astro": "^5.16.2",
|
||||||
"class-variance-authority": "^0.7.1",
|
"class-variance-authority": "^0.7.1",
|
||||||
@@ -4304,6 +4305,19 @@
|
|||||||
"wonka": "^6.3.2"
|
"wonka": "^6.3.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@urql/exchange-auth": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@urql/exchange-auth/-/exchange-auth-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-tj09xiOR2f1J2h8TE9uZWjRZipCdmDoTewEytOacDQ+0Teo+yIZxm3ppHxolQtiA51OHrGYiNTkMte8HtfvaBw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@urql/core": "^6.0.0",
|
||||||
|
"wonka": "^6.3.2"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@urql/core": "^6.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@urql/svelte": {
|
"node_modules/@urql/svelte": {
|
||||||
"version": "5.0.0",
|
"version": "5.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@urql/svelte/-/svelte-5.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/@urql/svelte/-/svelte-5.0.0.tgz",
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
"@astrojs/svelte": "^7.2.2",
|
"@astrojs/svelte": "^7.2.2",
|
||||||
"@tailwindcss/vite": "^4.1.17",
|
"@tailwindcss/vite": "^4.1.17",
|
||||||
"@urql/core": "^6.0.1",
|
"@urql/core": "^6.0.1",
|
||||||
|
"@urql/exchange-auth": "^3.0.0",
|
||||||
"@urql/svelte": "^5.0.0",
|
"@urql/svelte": "^5.0.0",
|
||||||
"astro": "^5.16.2",
|
"astro": "^5.16.2",
|
||||||
"class-variance-authority": "^0.7.1",
|
"class-variance-authority": "^0.7.1",
|
||||||
|
|||||||
@@ -117,3 +117,14 @@ export async function logout() {
|
|||||||
user.set(null);
|
user.set(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function refreshToken(): Promise<User | null> {
|
||||||
|
if (!userManager) return null;
|
||||||
|
try {
|
||||||
|
const newUser = await userManager.signinSilent();
|
||||||
|
return newUser;
|
||||||
|
} catch (e) {
|
||||||
|
console.error('Token refresh failed:', e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ const authority = import.meta.env.PUBLIC_OIDC_AUTHORITY;
|
|||||||
const clientId = import.meta.env.PUBLIC_OIDC_CLIENT_ID;
|
const clientId = import.meta.env.PUBLIC_OIDC_CLIENT_ID;
|
||||||
const redirectUri = import.meta.env.PUBLIC_OIDC_REDIRECT_URI;
|
const redirectUri = import.meta.env.PUBLIC_OIDC_REDIRECT_URI;
|
||||||
const postLogoutRedirectUri = import.meta.env.PUBLIC_OIDC_POST_LOGOUT_REDIRECT_URI ?? redirectUri;
|
const postLogoutRedirectUri = import.meta.env.PUBLIC_OIDC_POST_LOGOUT_REDIRECT_URI ?? redirectUri;
|
||||||
const scope = import.meta.env.PUBLIC_OIDC_SCOPE ?? 'openid profile email';
|
const scope = import.meta.env.PUBLIC_OIDC_SCOPE ?? 'openid profile email offline_access';
|
||||||
|
|
||||||
export const isOidcConfigured =
|
export const isOidcConfigured =
|
||||||
Boolean(authority) && Boolean(clientId) && Boolean(redirectUri);
|
Boolean(authority) && Boolean(clientId) && Boolean(redirectUri);
|
||||||
@@ -20,7 +20,7 @@ function buildSettings(): UserManagerSettings | null {
|
|||||||
response_type: 'code',
|
response_type: 'code',
|
||||||
scope,
|
scope,
|
||||||
loadUserInfo: true,
|
loadUserInfo: true,
|
||||||
automaticSilentRenew: true,
|
automaticSilentRenew: false, // We handle refresh reactively via authExchange
|
||||||
userStore:
|
userStore:
|
||||||
typeof window !== 'undefined'
|
typeof window !== 'undefined'
|
||||||
? new WebStorageStateStore({ store: window.localStorage })
|
? new WebStorageStateStore({ store: window.localStorage })
|
||||||
|
|||||||
@@ -1,19 +1,36 @@
|
|||||||
import { Client, cacheExchange, fetchExchange } from '@urql/core';
|
import { Client, cacheExchange, fetchExchange } from '@urql/core';
|
||||||
|
import { authExchange } from '@urql/exchange-auth';
|
||||||
import { get } from 'svelte/store';
|
import { get } from 'svelte/store';
|
||||||
import { user } from '../auth/authStore';
|
import { user, refreshToken } from '../auth/authStore';
|
||||||
|
|
||||||
export function createClient() {
|
export function createClient() {
|
||||||
return new Client({
|
return new Client({
|
||||||
url: import.meta.env.PUBLIC_GRAPHQL_URI,
|
url: import.meta.env.PUBLIC_GRAPHQL_URI,
|
||||||
exchanges: [cacheExchange, fetchExchange],
|
exchanges: [
|
||||||
fetchOptions: () => {
|
cacheExchange,
|
||||||
const currentUser = get(user);
|
authExchange(async (utils) => ({
|
||||||
return {
|
addAuthToOperation(operation) {
|
||||||
headers: currentUser?.access_token
|
const currentUser = get(user);
|
||||||
? { Authorization: `Bearer ${currentUser.access_token}` }
|
if (!currentUser?.access_token) return operation;
|
||||||
: {},
|
return utils.appendHeaders(operation, {
|
||||||
};
|
Authorization: `Bearer ${currentUser.access_token}`,
|
||||||
},
|
});
|
||||||
|
},
|
||||||
|
didAuthError(error) {
|
||||||
|
return error.graphQLErrors?.some(
|
||||||
|
(e) => e.extensions?.code === 'AUTH_NOT_AUTHENTICATED'
|
||||||
|
);
|
||||||
|
},
|
||||||
|
async refreshAuth() {
|
||||||
|
const newUser = await refreshToken();
|
||||||
|
if (!newUser) {
|
||||||
|
// Refresh failed, redirect to login
|
||||||
|
window.location.href = '/';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})),
|
||||||
|
fetchExchange,
|
||||||
|
],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user