Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/nextjs-signed-out-defaults.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@asgardeo/nextjs': patch
---

`useAsgardeo().user` and the current organization are `null` instead of empty objects while signed out or unavailable, so `<User fallback>` and `<Organization fallback>` render their fallbacks and `OrganizationSwitcher` no longer offers to manage an organization with an empty ID. With `preferences.user.fetchUserProfile` set to `false`, the user and profile are now populated from the ID token claims, as in the React SDK, instead of being left empty.
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ export type AsgardeoClientProviderProps = Partial<Omit<AsgardeoProviderProps, 'b
brandingPreference?: BrandingPreference | null;
clearSession: () => Promise<void>;
createOrganization: (payload: CreateOrganizationPayload, sessionId: string) => Promise<Organization>;
currentOrganization: Organization;
currentOrganization: Organization | null;
getAllOrganizations: (options?: any, sessionId?: string) => Promise<AllOrganizationsApiResponse>;
handleOAuthCallback: (
code: string,
Expand Down
35 changes: 26 additions & 9 deletions packages/nextjs/src/server/AsgardeoProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,15 @@

'use server';

import {BrandingPreference, AsgardeoRuntimeError, IdToken, Organization, User, UserProfile} from '@asgardeo/node';
import {
BrandingPreference,
AsgardeoRuntimeError,
IdToken,
Organization,
User,
UserProfile,
extractUserClaimsFromIdToken,
} from '@asgardeo/node';
import {AsgardeoProviderProps} from '@asgardeo/react';
import {FC, PropsWithChildren, ReactElement} from 'react';
import clearSession from './actions/clearSession';
Expand Down Expand Up @@ -116,17 +124,15 @@ const AsgardeoServerProvider: FC<PropsWithChildren<AsgardeoServerProviderProps>>
const sessionId: string = sessionPayload?.sessionId || (await getSessionId()) || '';
const signedIn: boolean = await isSignedIn(sessionId);

let user: User = {};
// `null` (not an empty object) while signed out or unavailable, so that `<User>` / `<Organization>` render
// their fallbacks and `useAsgardeo().user` can be checked for truthiness, as in the React SDK.
let user: User | null = null;
let userProfile: UserProfile = {
flattenedProfile: {},
profile: {},
schemas: [],
};
let currentOrganization: Organization = {
id: '',
name: '',
orgHandle: '',
};
let currentOrganization: Organization | null = null;
let myOrganizations: Organization[] = [];
let brandingPreference: BrandingPreference | null = null;

Expand Down Expand Up @@ -166,11 +172,22 @@ const AsgardeoServerProvider: FC<PropsWithChildren<AsgardeoServerProviderProps>>
success: boolean;
} = await getUserProfileAction(sessionId);

user = userResponse.data?.user || {};
user = userResponse.data?.user ?? null;
userProfile = userProfileResponse.data?.userProfile ?? userProfile;
} catch (error) {
logger.warn('[AsgardeoServerProvider] Failed to fetch user profile from SCIM2:', error?.toString());
}
} else {
// Profile fetching is disabled: expose the claims of the ID token instead, as the React SDK does, so
// that `user` and `<UserProfile />` are not empty.
try {
const claims: User = extractUserClaimsFromIdToken(await asgardeoClient.getDecodedIdToken(sessionId)) as User;

user = claims;
userProfile = {flattenedProfile: claims, profile: claims, schemas: []};
} catch (error) {
logger.warn('[AsgardeoServerProvider] Failed to read the user claims from the ID token:', error?.toString());
}
}

if (shouldFetchOrganizations) {
Expand All @@ -187,7 +204,7 @@ const AsgardeoServerProvider: FC<PropsWithChildren<AsgardeoServerProviderProps>>
logger.warn('[AsgardeoServerProvider] No session ID available, skipping organization fetch');
}

currentOrganization = currentOrganizationResponse?.data?.organization as Organization;
currentOrganization = currentOrganizationResponse?.data?.organization ?? null;
} catch (error) {
logger.warn('[AsgardeoServerProvider] Failed to fetch organization info:', error?.toString());
}
Expand Down
Loading