@undefineds.co/xpod 0.3.52 → 0.3.53

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -32,10 +32,17 @@ async function refreshStoredOidcSession(credentials, secrets) {
32
32
  if (!session)
33
33
  return null;
34
34
  let refreshedTokenSet = null;
35
- session.events.on(solid_client_authn_node_1.EVENTS.NEW_TOKENS, (tokenSet) => {
35
+ const onNewTokens = (tokenSet) => {
36
36
  refreshedTokenSet = tokenSet;
37
- });
38
- await (0, solid_client_authn_node_1.refreshSession)(session, { storage });
37
+ };
38
+ session.events.on(solid_client_authn_node_1.EVENTS.NEW_TOKENS, onNewTokens);
39
+ try {
40
+ await (0, solid_client_authn_node_1.refreshSession)(session, { storage });
41
+ }
42
+ finally {
43
+ removeSessionListener(session, solid_client_authn_node_1.EVENTS.NEW_TOKENS, onNewTokens);
44
+ disposeOneShotRefreshTimer(session);
45
+ }
39
46
  const nextTokenSet = refreshedTokenSet;
40
47
  if (!nextTokenSet?.accessToken)
41
48
  return null;
@@ -53,6 +60,23 @@ async function refreshStoredOidcSession(credentials, secrets) {
53
60
  });
54
61
  return nextTokenSet.accessToken;
55
62
  }
63
+ function removeSessionListener(session, eventName, listener) {
64
+ const events = session?.events;
65
+ if (typeof events?.off === 'function') {
66
+ events.off(eventName, listener);
67
+ return;
68
+ }
69
+ if (typeof events?.removeListener === 'function') {
70
+ events.removeListener(eventName, listener);
71
+ }
72
+ }
73
+ function disposeOneShotRefreshTimer(session) {
74
+ const timeoutHandle = session
75
+ ?.lastTimeoutHandle;
76
+ if (timeoutHandle) {
77
+ clearTimeout(timeoutHandle);
78
+ }
79
+ }
56
80
  async function resolveStoredOidcSessionId(storage, webId, issuerUrl) {
57
81
  const raw = await storage.get('solidClientAuthn:registeredSessions');
58
82
  if (!raw)
@@ -1 +1 @@
1
- {"version":3,"file":"oidc-auth.js","sourceRoot":"","sources":["../../../src/cli/lib/oidc-auth.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n EVENTS,\n getSessionFromStorage,\n refreshSession,\n type SessionTokenSet,\n} from '@inrupt/solid-client-authn-node';\nimport {\n getOAuthCredentials,\n saveCredentials,\n type OidcOAuthSecrets,\n type StoredCredentials,\n} from './credentials-store';\nimport { createOidcSessionStorage } from './oidc-session-storage';\n\nconst TOKEN_EXPIRY_SKEW_MS = 60_000;\n\nexport async function getOidcAccessToken(\n credentials: StoredCredentials,\n options: { forceRefresh?: boolean } = {},\n): Promise<string | null> {\n const secrets = getOAuthCredentials(credentials);\n if (!secrets) return null;\n\n if (!options.forceRefresh && isUsableAccessToken(secrets)) {\n return secrets.oidcAccessToken;\n }\n\n return refreshStoredOidcSession(credentials, secrets);\n}\n\nfunction isUsableAccessToken(secrets: OidcOAuthSecrets): boolean {\n if (!secrets.oidcAccessToken) return false;\n const expiresAt = new Date(secrets.oidcExpiresAt).getTime();\n return Number.isFinite(expiresAt) && expiresAt > Date.now() + TOKEN_EXPIRY_SKEW_MS;\n}\n\nasync function refreshStoredOidcSession(\n credentials: StoredCredentials,\n secrets: OidcOAuthSecrets,\n): Promise<string | null> {\n const storage = createOidcSessionStorage();\n const sessionId = await resolveStoredOidcSessionId(storage, credentials.webId, credentials.url);\n if (!sessionId) return null;\n\n const session = await getSessionFromStorage(sessionId, {\n storage,\n refreshSession: false,\n });\n if (!session) return null;\n\n let refreshedTokenSet: SessionTokenSet | null = null;\n session.events.on(EVENTS.NEW_TOKENS, (tokenSet) => {\n refreshedTokenSet = tokenSet;\n });\n\n await refreshSession(session, { storage });\n\n const nextTokenSet = refreshedTokenSet as SessionTokenSet | null;\n if (!nextTokenSet?.accessToken) return null;\n\n secrets.oidcRefreshToken = nextTokenSet.refreshToken ?? secrets.oidcRefreshToken;\n secrets.oidcAccessToken = nextTokenSet.accessToken;\n secrets.oidcExpiresAt = nextTokenSet.expiresAt\n ? new Date(nextTokenSet.expiresAt * 1000).toISOString()\n : secrets.oidcExpiresAt;\n secrets.oidcClientId = nextTokenSet.clientId ?? secrets.oidcClientId;\n\n saveCredentials({\n url: credentials.url,\n webId: session.info.webId ?? credentials.webId,\n authType: 'oidc_oauth',\n secrets,\n });\n\n return nextTokenSet.accessToken;\n}\n\nasync function resolveStoredOidcSessionId(\n storage: ReturnType<typeof createOidcSessionStorage>,\n webId: string,\n issuerUrl: string,\n): Promise<string | null> {\n const raw = await storage.get('solidClientAuthn:registeredSessions');\n if (!raw) return null;\n\n let sessionIds: string[] = [];\n try {\n const parsed = JSON.parse(raw) as unknown;\n if (Array.isArray(parsed)) {\n sessionIds = parsed.filter((value): value is string => typeof value === 'string');\n }\n } catch {\n return null;\n }\n\n const normalizedIssuer = issuerUrl.replace(/\\/+$/u, '');\n for (const sessionId of [...sessionIds].reverse()) {\n const stored = await storage.get(`solidClientAuthenticationUser:${sessionId}`);\n if (!stored) continue;\n\n try {\n const parsed = JSON.parse(stored) as { webId?: string; issuer?: string; dpop?: string | boolean };\n const sessionWebId = typeof parsed.webId === 'string' ? parsed.webId : null;\n const sessionIssuer = typeof parsed.issuer === 'string' ? parsed.issuer.replace(/\\/+$/u, '') : null;\n const sessionUsesDpop = parsed.dpop === true || parsed.dpop === 'true';\n if (sessionWebId === webId && sessionIssuer === normalizedIssuer && !sessionUsesDpop) {\n return sessionId;\n }\n } catch {\n continue;\n }\n }\n\n return null;\n}\n"]}
1
+ {"version":3,"file":"oidc-auth.js","sourceRoot":"","sources":["../../../src/cli/lib/oidc-auth.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n EVENTS,\n getSessionFromStorage,\n refreshSession,\n type SessionTokenSet,\n} from '@inrupt/solid-client-authn-node';\nimport {\n getOAuthCredentials,\n saveCredentials,\n type OidcOAuthSecrets,\n type StoredCredentials,\n} from './credentials-store';\nimport { createOidcSessionStorage } from './oidc-session-storage';\n\nconst TOKEN_EXPIRY_SKEW_MS = 60_000;\n\nexport async function getOidcAccessToken(\n credentials: StoredCredentials,\n options: { forceRefresh?: boolean } = {},\n): Promise<string | null> {\n const secrets = getOAuthCredentials(credentials);\n if (!secrets) return null;\n\n if (!options.forceRefresh && isUsableAccessToken(secrets)) {\n return secrets.oidcAccessToken;\n }\n\n return refreshStoredOidcSession(credentials, secrets);\n}\n\nfunction isUsableAccessToken(secrets: OidcOAuthSecrets): boolean {\n if (!secrets.oidcAccessToken) return false;\n const expiresAt = new Date(secrets.oidcExpiresAt).getTime();\n return Number.isFinite(expiresAt) && expiresAt > Date.now() + TOKEN_EXPIRY_SKEW_MS;\n}\n\nasync function refreshStoredOidcSession(\n credentials: StoredCredentials,\n secrets: OidcOAuthSecrets,\n): Promise<string | null> {\n const storage = createOidcSessionStorage();\n const sessionId = await resolveStoredOidcSessionId(storage, credentials.webId, credentials.url);\n if (!sessionId) return null;\n\n const session = await getSessionFromStorage(sessionId, {\n storage,\n refreshSession: false,\n });\n if (!session) return null;\n\n let refreshedTokenSet: SessionTokenSet | null = null;\n const onNewTokens = (tokenSet: SessionTokenSet): void => {\n refreshedTokenSet = tokenSet;\n };\n session.events.on(EVENTS.NEW_TOKENS, onNewTokens);\n\n try {\n await refreshSession(session, { storage });\n } finally {\n removeSessionListener(session, EVENTS.NEW_TOKENS, onNewTokens);\n disposeOneShotRefreshTimer(session);\n }\n\n const nextTokenSet = refreshedTokenSet as SessionTokenSet | null;\n if (!nextTokenSet?.accessToken) return null;\n\n secrets.oidcRefreshToken = nextTokenSet.refreshToken ?? secrets.oidcRefreshToken;\n secrets.oidcAccessToken = nextTokenSet.accessToken;\n secrets.oidcExpiresAt = nextTokenSet.expiresAt\n ? new Date(nextTokenSet.expiresAt * 1000).toISOString()\n : secrets.oidcExpiresAt;\n secrets.oidcClientId = nextTokenSet.clientId ?? secrets.oidcClientId;\n\n saveCredentials({\n url: credentials.url,\n webId: session.info.webId ?? credentials.webId,\n authType: 'oidc_oauth',\n secrets,\n });\n\n return nextTokenSet.accessToken;\n}\n\nfunction removeSessionListener(\n session: Awaited<ReturnType<typeof getSessionFromStorage>>,\n eventName: string,\n listener: (tokenSet: SessionTokenSet) => void,\n): void {\n const events = session?.events as {\n off?: (eventName: string, listener: (tokenSet: SessionTokenSet) => void) => void;\n removeListener?: (eventName: string, listener: (tokenSet: SessionTokenSet) => void) => void;\n } | undefined;\n\n if (typeof events?.off === 'function') {\n events.off(eventName, listener);\n return;\n }\n if (typeof events?.removeListener === 'function') {\n events.removeListener(eventName, listener);\n }\n}\n\nfunction disposeOneShotRefreshTimer(session: Awaited<ReturnType<typeof getSessionFromStorage>>): void {\n const timeoutHandle = (session as { lastTimeoutHandle?: ReturnType<typeof setTimeout> | number } | null | undefined)\n ?.lastTimeoutHandle;\n if (timeoutHandle) {\n clearTimeout(timeoutHandle as ReturnType<typeof setTimeout>);\n }\n}\n\nasync function resolveStoredOidcSessionId(\n storage: ReturnType<typeof createOidcSessionStorage>,\n webId: string,\n issuerUrl: string,\n): Promise<string | null> {\n const raw = await storage.get('solidClientAuthn:registeredSessions');\n if (!raw) return null;\n\n let sessionIds: string[] = [];\n try {\n const parsed = JSON.parse(raw) as unknown;\n if (Array.isArray(parsed)) {\n sessionIds = parsed.filter((value): value is string => typeof value === 'string');\n }\n } catch {\n return null;\n }\n\n const normalizedIssuer = issuerUrl.replace(/\\/+$/u, '');\n for (const sessionId of [...sessionIds].reverse()) {\n const stored = await storage.get(`solidClientAuthenticationUser:${sessionId}`);\n if (!stored) continue;\n\n try {\n const parsed = JSON.parse(stored) as { webId?: string; issuer?: string; dpop?: string | boolean };\n const sessionWebId = typeof parsed.webId === 'string' ? parsed.webId : null;\n const sessionIssuer = typeof parsed.issuer === 'string' ? parsed.issuer.replace(/\\/+$/u, '') : null;\n const sessionUsesDpop = parsed.dpop === true || parsed.dpop === 'true';\n if (sessionWebId === webId && sessionIssuer === normalizedIssuer && !sessionUsesDpop) {\n return sessionId;\n }\n } catch {\n continue;\n }\n }\n\n return null;\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@undefineds.co/xpod",
3
- "version": "0.3.52",
3
+ "version": "0.3.53",
4
4
  "description": "Xpod is an extended Community Solid Server, offering rich-feature, production-level Solid Pod and identity management.",
5
5
  "repository": "https://github.com/undefinedsco/xpod",
6
6
  "author": "developer@undefineds.co",