diff --git a/packages/sdk/src/modules/analytics.ts b/packages/sdk/src/modules/analytics.ts index 62fcb27c..5a91b17d 100644 --- a/packages/sdk/src/modules/analytics.ts +++ b/packages/sdk/src/modules/analytics.ts @@ -9,7 +9,7 @@ import { SessionContext, } from "./analytics.types"; import { getSharedInstance } from "../utils/sharedInstance.js"; -import type { InternalAuthModule } from "./auth.types"; +import type { AuthModule } from "./auth.types"; import { generateUuid, isReactNative } from "../utils/common.js"; export const USER_HEARTBEAT_EVENT_NAME = "__user_heartbeat_event__"; @@ -61,7 +61,7 @@ export interface AnalyticsModuleArgs { axiosClient: AxiosInstance; serverUrl: string; appId: string; - userAuthModule: InternalAuthModule; + userAuthModule: AuthModule; enabled: boolean; } @@ -360,7 +360,7 @@ export function resetAnalyticsSessionContext() { } async function getSessionContext( - userAuthModule: InternalAuthModule + userAuthModule: AuthModule ): Promise { if (!analyticsSharedState.sessionContext) { // With no token there is no identity to resolve: `me()` can only answer 401, diff --git a/packages/sdk/src/modules/auth.ts b/packages/sdk/src/modules/auth.ts index b9e23747..111b886d 100644 --- a/packages/sdk/src/modules/auth.ts +++ b/packages/sdk/src/modules/auth.ts @@ -1,7 +1,7 @@ import { AxiosInstance } from "axios"; import { AuthModuleOptions, - InternalAuthModule, + AuthModule, User, VerifyOtpParams, ChangePasswordParams, @@ -92,7 +92,7 @@ export function createAuthModule( functionsAxiosClient: AxiosInstance, appId: string, options: AuthModuleOptions -): InternalAuthModule { +): AuthModule { // In-flight `me()` request, shared by concurrent callers. The analytics // module resolves its session context through `me()` at client construction, // at the same moment most apps issue their own `me()`. Browsers serialize the diff --git a/packages/sdk/src/modules/auth.types.ts b/packages/sdk/src/modules/auth.types.ts index 7c080efe..c99ba43c 100644 --- a/packages/sdk/src/modules/auth.types.ts +++ b/packages/sdk/src/modules/auth.types.ts @@ -344,6 +344,21 @@ export interface AuthModule { */ isAuthenticated(): Promise; + /** + * Checks whether an access token is currently set on the client. + * + * Reports only that a token is present, not that it's valid: an expired or revoked token still returns `true`. Use it to skip requests that can't succeed without a session, such as {@linkcode me | me()} for an anonymous visitor, and use {@linkcode isAuthenticated | isAuthenticated()} to confirm a session with the server. The token is the one passed to {@linkcode createClient | createClient()} or set with {@linkcode setToken | setToken()}, and {@linkcode logout | logout()} clears it. A session held only in an HTTP-only cookie isn't visible to the client and returns `false`. + * + * @returns `true` if the client has an access token, `false` otherwise. + * + * @example + * ```typescript + * // Skip the user lookup for anonymous visitors + * const user = base44.auth.hasToken() ? await base44.auth.me() : null; + * ``` + */ + hasToken(): boolean; + /** * Invites a user to the app. * @@ -552,21 +567,3 @@ export interface AuthModule { */ changePassword(params: ChangePasswordParams): Promise; } - -/** - * The auth module as constructed internally, before it is narrowed to - * {@link AuthModule} on the public client. Not exported from the package - * index — SDK consumers see only {@link AuthModule}. - * - * @internal - */ -export interface InternalAuthModule extends AuthModule { - /** - * Whether an access token is currently set on the client. - * - * Reports only the presence of a token, never its validity — an expired or - * revoked token still reads as `true`. Callers use this to skip requests that - * could not succeed without a session, not to decide that one is valid. - */ - hasToken(): boolean; -} diff --git a/packages/sdk/tests/unit/analytics.test.ts b/packages/sdk/tests/unit/analytics.test.ts index d851e99c..bad1da6e 100644 --- a/packages/sdk/tests/unit/analytics.test.ts +++ b/packages/sdk/tests/unit/analytics.test.ts @@ -7,7 +7,7 @@ import { } from "../../src/index.ts"; import { getSharedInstance } from "../../src/utils/sharedInstance.ts"; import { resetAnalyticsSessionContext } from "../../src/modules/analytics.ts"; -import { InternalAuthModule, User } from "../../src/modules/auth.types.ts"; +import { User } from "../../src/modules/auth.types.ts"; import { AxiosInstance } from "axios"; describe("Analytics Module", () => { @@ -246,9 +246,7 @@ describe("Analytics Module", () => { test("should report token presence across identity changes", () => { const client = createClient({ serverUrl, appId }); - // `hasToken` lives on the internal auth surface only; the public client - // narrows to AuthModule, so reach past the narrowing deliberately here. - const auth = client.auth as InternalAuthModule; + const auth = client.auth; expect(auth.hasToken()).toBe(false);