diff --git a/packages/angular/package.json b/packages/angular/package.json index 4693e6f..7222466 100644 --- a/packages/angular/package.json +++ b/packages/angular/package.json @@ -1,6 +1,6 @@ { "name": "oidc-js-angular", - "version": "1.0.8", + "version": "1.1.0", "description": "Simple OIDC authentication for Angular. Signals, DI, and route guards with zero dependencies.", "type": "module", "main": "./dist/index.cjs", diff --git a/packages/angular/src/auth.service.ts b/packages/angular/src/auth.service.ts index ea0bf97..68fb0a1 100644 --- a/packages/angular/src/auth.service.ts +++ b/packages/angular/src/auth.service.ts @@ -127,8 +127,8 @@ export class AuthService { * * @throws Error if no refresh token is available. */ - async refresh(): Promise { - await this.client.refresh(); + async refresh() { + return this.client.refresh(); } /** @@ -136,7 +136,7 @@ export class AuthService { * * @throws Error if no access token is available. */ - async fetchProfile(): Promise { - await this.client.fetchProfile(); + async fetchProfile() { + return this.client.fetchProfile(); } } diff --git a/packages/client/package.json b/packages/client/package.json index 8df8783..89fd4fb 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -1,6 +1,6 @@ { "name": "oidc-js", - "version": "1.0.8", + "version": "1.1.0", "description": "Simple OIDC authentication for JavaScript. Drop-in client with login, logout, token refresh, and zero dependencies.", "type": "module", "main": "./dist/index.cjs", diff --git a/packages/client/src/client.ts b/packages/client/src/client.ts index f68e155..ceb8f7d 100644 --- a/packages/client/src/client.ts +++ b/packages/client/src/client.ts @@ -51,7 +51,7 @@ export class OidcClient { private discovery: OidcDiscovery | null = null; private subscribers = new Set(); private abortController: AbortController | null = null; - private refreshPromise: Promise | null = null; + private refreshPromise: Promise | null = null; private _state: AuthState = { user: null, @@ -243,7 +243,7 @@ export class OidcClient { * * @throws Error if no refresh token is available or discovery has not been fetched. */ - async refresh(): Promise { + async refresh(): Promise { if (this.refreshPromise) { return this.refreshPromise; } @@ -255,7 +255,7 @@ export class OidcClient { return this.refreshPromise; } - private async refreshInternal(): Promise { + private async refreshInternal(): Promise { const refreshToken = this._state.tokens.refresh; if (!this.discovery || !refreshToken) { @@ -289,6 +289,8 @@ export class OidcClient { isAuthenticated: true, error: null, }); + + return newTokens; } /** @@ -298,7 +300,7 @@ export class OidcClient { * * @throws Error if no access token is available or discovery has not been fetched. */ - async fetchProfile(): Promise { + async fetchProfile(): Promise { if (!this.discovery || !this._state.tokens.access) { throw new Error("No access token available"); } @@ -307,6 +309,7 @@ export class OidcClient { if (this._state.user) { this.setState({ user: { ...this._state.user, profile } }); } + return profile; } /** diff --git a/packages/core/package.json b/packages/core/package.json index e795d71..b17e65d 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "oidc-js-core", - "version": "1.0.8", + "version": "1.1.0", "description": "Zero-dependency OIDC/OAuth 2.0 functions for JavaScript. Pure, functional, works everywhere.", "type": "module", "main": "./dist/index.cjs", diff --git a/packages/kasper/package.json b/packages/kasper/package.json index c72d7e4..3d03a95 100644 --- a/packages/kasper/package.json +++ b/packages/kasper/package.json @@ -1,6 +1,6 @@ { "name": "oidc-js-kasper", - "version": "1.0.8", + "version": "1.1.0", "description": "Simple OIDC authentication for Kasper.js. Signals, components, and auth guards with zero dependencies.", "type": "module", "main": "./dist/index.cjs", diff --git a/packages/kasper/src/types.ts b/packages/kasper/src/types.ts index c7b4f15..49cebd4 100644 --- a/packages/kasper/src/types.ts +++ b/packages/kasper/src/types.ts @@ -1,6 +1,7 @@ import type { Signal } from "kasper-js"; import type { OidcConfig } from "oidc-js-core"; import type { AuthUser, AuthTokens, LoginOptions } from "oidc-js"; +import type { OidcUser } from "oidc-js-core"; export type { IdTokenClaims, AuthUser, AuthTokens, LoginOptions } from "oidc-js"; export type { Signal } from "kasper-js"; @@ -12,9 +13,9 @@ export interface AuthActions { /** Logs the user out and redirects to the post-logout URI. */ logout: () => void; /** Refreshes the access token using the refresh token. */ - refresh: () => Promise; + refresh: () => Promise; /** Fetches the user's profile from the userinfo endpoint. */ - fetchProfile: () => Promise; + fetchProfile: () => Promise; } /** Value returned by {@link useAuth}. All state properties are Kasper signals. */ diff --git a/packages/lit/package.json b/packages/lit/package.json index ae7ff3d..32c8f9d 100644 --- a/packages/lit/package.json +++ b/packages/lit/package.json @@ -1,6 +1,6 @@ { "name": "oidc-js-lit", - "version": "1.0.8", + "version": "1.1.0", "description": "Simple OIDC authentication for Lit. Reactive controllers for login, logout, and token refresh with zero dependencies.", "type": "module", "main": "./dist/index.cjs", diff --git a/packages/lit/src/auth-controller.ts b/packages/lit/src/auth-controller.ts index 75e0b8b..b057224 100644 --- a/packages/lit/src/auth-controller.ts +++ b/packages/lit/src/auth-controller.ts @@ -148,8 +148,9 @@ export class AuthController implements ReactiveController { * * @throws Error if no refresh token is available or discovery has not been fetched. */ - async refresh(): Promise { - await this.client?.refresh(); + async refresh() { + const result = await this.client?.refresh(); + return result ?? { access: null, id: null, refresh: null, expiresAt: null }; } /** @@ -157,7 +158,7 @@ export class AuthController implements ReactiveController { * * @throws Error if no access token is available or discovery has not been fetched. */ - async fetchProfile(): Promise { - await this.client?.fetchProfile(); + async fetchProfile() { + return (await this.client?.fetchProfile()) ?? null; } } diff --git a/packages/lit/src/types.ts b/packages/lit/src/types.ts index bb2c4dd..4619d7a 100644 --- a/packages/lit/src/types.ts +++ b/packages/lit/src/types.ts @@ -2,7 +2,8 @@ import type { OidcConfig } from "oidc-js-core"; export type { IdTokenClaims, AuthUser, AuthTokens, LoginOptions } from "oidc-js"; -import type { LoginOptions } from "oidc-js"; +import type { AuthTokens, LoginOptions } from "oidc-js"; +import type { OidcUser } from "oidc-js-core"; /** * Actions available on the {@link AuthController} for triggering authentication operations. @@ -13,9 +14,9 @@ export interface AuthActions { /** Logs the user out and redirects to the OP's end-session endpoint. */ logout: () => void; /** Uses the stored refresh token to obtain new tokens. */ - refresh: () => Promise; + refresh: () => Promise; /** Fetches the user's profile from the userinfo endpoint. */ - fetchProfile: () => Promise; + fetchProfile: () => Promise; } /** diff --git a/packages/preact/package.json b/packages/preact/package.json index adbd9f8..86a748e 100644 --- a/packages/preact/package.json +++ b/packages/preact/package.json @@ -1,6 +1,6 @@ { "name": "oidc-js-preact", - "version": "1.0.8", + "version": "1.1.0", "description": "Simple OIDC authentication for Preact. Hooks, provider, and auth guards with zero dependencies.", "type": "module", "main": "./dist/index.cjs", diff --git a/packages/preact/src/context.tsx b/packages/preact/src/context.tsx index 79b25e8..f75d63a 100644 --- a/packages/preact/src/context.tsx +++ b/packages/preact/src/context.tsx @@ -88,11 +88,12 @@ export function AuthProvider({ }, []); const refresh = useCallback(async () => { - await clientRef.current?.refresh(); + const result = await clientRef.current?.refresh(); + return result ?? { access: null, id: null, refresh: null, expiresAt: null }; }, []); const doFetchProfile = useCallback(async () => { - await clientRef.current?.fetchProfile(); + return (await clientRef.current?.fetchProfile()) ?? null; }, []); const actions = useMemo( diff --git a/packages/preact/src/types.ts b/packages/preact/src/types.ts index f017cf1..5262c37 100644 --- a/packages/preact/src/types.ts +++ b/packages/preact/src/types.ts @@ -3,6 +3,7 @@ import type { OidcConfig } from "oidc-js-core"; export type { IdTokenClaims, AuthUser, AuthTokens, LoginOptions } from "oidc-js"; import type { AuthUser, AuthTokens, LoginOptions } from "oidc-js"; +import type { OidcUser } from "oidc-js-core"; /** Actions available for controlling the authentication lifecycle. */ export interface AuthActions { @@ -11,9 +12,9 @@ export interface AuthActions { /** Logs the user out and optionally redirects to the OP's end-session endpoint. */ logout: () => void; /** Refreshes the access token using the stored refresh token. */ - refresh: () => Promise; + refresh: () => Promise; /** Fetches the user's profile from the userinfo endpoint. */ - fetchProfile: () => Promise; + fetchProfile: () => Promise; } /** The value provided by {@link AuthProvider} and consumed by {@link useAuth}. */ diff --git a/packages/react/package.json b/packages/react/package.json index 02f6a0d..df80926 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -1,6 +1,6 @@ { "name": "oidc-js-react", - "version": "1.0.8", + "version": "1.1.0", "description": "Simple OIDC authentication for React. Provider, hooks, and route guards with zero dependencies.", "type": "module", "main": "./dist/index.cjs", diff --git a/packages/react/src/context.tsx b/packages/react/src/context.tsx index 9573b97..9b88b8b 100644 --- a/packages/react/src/context.tsx +++ b/packages/react/src/context.tsx @@ -80,11 +80,12 @@ export function AuthProvider({ }, []); const refresh = useCallback(async () => { - await clientRef.current?.refresh(); + const result = await clientRef.current?.refresh(); + return result ?? { access: null, id: null, refresh: null, expiresAt: null }; }, []); const doFetchProfile = useCallback(async () => { - await clientRef.current?.fetchProfile(); + return (await clientRef.current?.fetchProfile()) ?? null; }, []); const actions = useMemo( @@ -93,7 +94,7 @@ export function AuthProvider({ ); const value: AuthContextValue = useMemo( - () => ({ config, ...state, actions }), + () => ({ config, client: clientRef.current!, ...state, actions }), [config, state, actions], ); diff --git a/packages/react/src/tests/auth-required.test.tsx b/packages/react/src/tests/auth-required.test.tsx index 9d76ba1..db6b210 100644 --- a/packages/react/src/tests/auth-required.test.tsx +++ b/packages/react/src/tests/auth-required.test.tsx @@ -25,6 +25,7 @@ function makeActions(overrides: Partial = {}) { function makeAuth(overrides: Partial = {}): AuthContextValue { return { config: { issuer: "https://auth.example.com", clientId: "app" }, + client: {} as AuthContextValue["client"], user: null, isAuthenticated: false, isLoading: false, diff --git a/packages/react/src/types.ts b/packages/react/src/types.ts index b2b361b..07a7986 100644 --- a/packages/react/src/types.ts +++ b/packages/react/src/types.ts @@ -2,17 +2,19 @@ import type { OidcConfig } from "oidc-js-core"; export type { IdTokenClaims, AuthUser, AuthTokens, LoginOptions } from "oidc-js"; -import type { AuthUser, AuthTokens, LoginOptions } from "oidc-js"; +import type { OidcClient, AuthUser, AuthTokens, LoginOptions } from "oidc-js"; +import type { OidcUser } from "oidc-js-core"; export interface AuthActions { login: (options?: LoginOptions) => void; logout: () => void; - refresh: () => Promise; - fetchProfile: () => Promise; + refresh: () => Promise; + fetchProfile: () => Promise; } export interface AuthContextValue { config: OidcConfig; + client: OidcClient; user: AuthUser | null; isAuthenticated: boolean; isLoading: boolean; diff --git a/packages/solid/package.json b/packages/solid/package.json index 6cb924d..5131066 100644 --- a/packages/solid/package.json +++ b/packages/solid/package.json @@ -1,6 +1,6 @@ { "name": "oidc-js-solid", - "version": "1.0.8", + "version": "1.1.0", "description": "Simple OIDC authentication for SolidJS. Signals, context, and auth guards with zero dependencies.", "type": "module", "main": "./dist/index.cjs", diff --git a/packages/solid/src/context.tsx b/packages/solid/src/context.tsx index 743f04e..24c13e4 100644 --- a/packages/solid/src/context.tsx +++ b/packages/solid/src/context.tsx @@ -90,11 +90,12 @@ export const AuthProvider: ParentComponent = (props) => { }; const refresh = async () => { - await client?.refresh(); + const result = await client?.refresh(); + return result ?? { access: null, id: null, refresh: null, expiresAt: null }; }; const doFetchProfile = async () => { - await client?.fetchProfile(); + return (await client?.fetchProfile()) ?? null; }; const actions = { login, logout, refresh, fetchProfile: doFetchProfile }; diff --git a/packages/solid/src/types.ts b/packages/solid/src/types.ts index f3e5c67..fe4a8a8 100644 --- a/packages/solid/src/types.ts +++ b/packages/solid/src/types.ts @@ -3,6 +3,7 @@ import type { OidcConfig } from "oidc-js-core"; export type { IdTokenClaims, AuthUser, AuthTokens, LoginOptions } from "oidc-js"; import type { AuthUser, AuthTokens, LoginOptions } from "oidc-js"; +import type { OidcUser } from "oidc-js-core"; /** * Actions available for controlling authentication flow. @@ -15,9 +16,9 @@ export interface AuthActions { /** Logs out the current user and clears auth state. */ logout: () => void; /** Refreshes the access token using the stored refresh token. */ - refresh: () => Promise; + refresh: () => Promise; /** Fetches the user's profile from the userinfo endpoint. */ - fetchProfile: () => Promise; + fetchProfile: () => Promise; } /** diff --git a/packages/svelte/package.json b/packages/svelte/package.json index 430cec6..6597adb 100644 --- a/packages/svelte/package.json +++ b/packages/svelte/package.json @@ -1,6 +1,6 @@ { "name": "oidc-js-svelte", - "version": "1.0.8", + "version": "1.1.0", "description": "Simple OIDC authentication for Svelte 5. Context, runes, and auth guards with zero dependencies.", "type": "module", "svelte": "./dist/index.js", diff --git a/packages/svelte/src/types.ts b/packages/svelte/src/types.ts index df131f7..5b39f98 100644 --- a/packages/svelte/src/types.ts +++ b/packages/svelte/src/types.ts @@ -3,6 +3,7 @@ import type { OidcConfig } from "oidc-js-core"; export type { IdTokenClaims, AuthUser, AuthTokens, LoginOptions } from "oidc-js"; import type { AuthUser, AuthTokens, LoginOptions } from "oidc-js"; +import type { OidcUser } from "oidc-js-core"; /** Actions available to interact with the OIDC authentication flow. */ export interface AuthActions { @@ -11,9 +12,9 @@ export interface AuthActions { /** Logs the user out and redirects to the end-session endpoint. */ logout: () => void; /** Refreshes the access token using the stored refresh token. */ - refresh: () => Promise; + refresh: () => Promise; /** Fetches the user's profile from the userinfo endpoint. */ - fetchProfile: () => Promise; + fetchProfile: () => Promise; } /** Reactive authentication context value provided by {@link AuthProvider}. */ diff --git a/packages/vue/package.json b/packages/vue/package.json index fecdaea..8f813f6 100644 --- a/packages/vue/package.json +++ b/packages/vue/package.json @@ -1,6 +1,6 @@ { "name": "oidc-js-vue", - "version": "1.0.8", + "version": "1.1.0", "description": "Simple OIDC authentication for Vue. Plugin, composables, and navigation guards with zero dependencies.", "type": "module", "main": "./dist/index.cjs", diff --git a/packages/vue/src/plugin.ts b/packages/vue/src/plugin.ts index 7f15555..59af1b2 100644 --- a/packages/vue/src/plugin.ts +++ b/packages/vue/src/plugin.ts @@ -92,11 +92,11 @@ export const oidcPlugin = { }; const refresh = async () => { - await client.refresh(); + return client.refresh(); }; const doFetchProfile = async () => { - await client.fetchProfile(); + return client.fetchProfile(); }; const actions: AuthActions = { diff --git a/packages/vue/src/types.ts b/packages/vue/src/types.ts index 7e9d80b..202e3c7 100644 --- a/packages/vue/src/types.ts +++ b/packages/vue/src/types.ts @@ -3,6 +3,7 @@ import type { OidcConfig } from "oidc-js-core"; export type { IdTokenClaims, AuthUser, AuthTokens, LoginOptions } from "oidc-js"; import type { AuthUser, AuthTokens, LoginOptions } from "oidc-js"; +import type { OidcUser } from "oidc-js-core"; /** * Actions available for authentication operations. @@ -16,9 +17,9 @@ export interface AuthActions { /** Logs the user out and redirects to the OP's end-session endpoint. */ logout: () => void; /** Uses the stored refresh token to obtain a new set of tokens. */ - refresh: () => Promise; + refresh: () => Promise; /** Fetches the user's profile from the userinfo endpoint. */ - fetchProfile: () => Promise; + fetchProfile: () => Promise; } /**