Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
6fcfb9f
chore(nextjs): add `B2B` components
brionmario Jul 1, 2025
73fd44b
feat: implement theme detection and customization options
brionmario Jul 1, 2025
9ee4ef4
fix: update ThemeProvider prop from defaultColorScheme to mode
brionmario Jul 1, 2025
7d1b6ff
feat(javascript): add getBrandingPreference API and related models fo…
brionmario Jul 1, 2025
c9075e5
chore(javascript): rename OrganizationDetails to BrandingOrganization…
brionmario Jul 1, 2025
0a0b259
fix: enhance readonly field handling in BaseUserProfile component
brionmario Jul 1, 2025
f64265a
chore: add MultiInput component for handling multiple input values
brionmario Jul 1, 2025
f5b98d7
feat: refactor MultiInput component styles using useMemo for improved…
brionmario Jul 1, 2025
df5d062
feat: add PlusIcon styling to MultiInput component for improved UI
brionmario Jul 1, 2025
0d5e748
fix(javascript): enhance API request handling by integrating requestC…
brionmario Jul 1, 2025
08f0bc5
feat: implement updateUserProfile method across client and server com…
brionmario Jul 1, 2025
876eb23
fix(react): enhance OrganizationProvider with fetching state manageme…
brionmario Jul 1, 2025
8f2efc4
feat(react): add getDecodedIdToken method and refactor baseUrl handli…
brionmario Jul 1, 2025
82d6078
feat: update getDecodedIdToken method to accept an optional sessionId…
brionmario Jul 1, 2025
7d26677
feat(react): implement profile update handling in UserProfile and Asg…
brionmario Jul 1, 2025
05bc879
feat: enhance AsgardeoClient interface and implementations with optio…
brionmario Jul 1, 2025
9728186
feat: add missing organization-related scopes in AsgardeoProvider
brionmario Jul 1, 2025
8dfc78d
chore: add teamspace logo image to public assets
brionmario Jul 1, 2025
1066fef
feat: add patch updates for Asgardeo packages and fix profile issues
brionmario Jul 2, 2025
e4ecf2e
feat: add organizationHandle and applicationId support in Asgardeo co…
brionmario Jul 2, 2025
6b7e03b
chore: improve error handling and configuration management in Asgarde…
brionmario Jul 2, 2025
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
10 changes: 10 additions & 0 deletions .changeset/stupid-carrots-stay.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
'@asgardeo/browser': patch
'@asgardeo/express': patch
'@asgardeo/javascript': patch
'@asgardeo/nextjs': patch
'@asgardeo/node': patch
'@asgardeo/react': patch
---

Fix issues with profile
6 changes: 3 additions & 3 deletions packages/browser/src/__legacy__/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ import {SPAUtils} from './utils';
* Default configurations.
*/
const DefaultConfig: Partial<AuthClientConfig<Config>> = {
autoLogoutOnTokenRefreshError: true,
autoLogoutOnTokenRefreshError: false,
checkSessionInterval: 3,
enableOIDCSessionManagement: false,
periodicTokenRefresh: false,
Expand Down Expand Up @@ -737,10 +737,10 @@ export class AsgardeoSPAClient {
*
* @preserve
*/
public async getDecodedIdToken(): Promise<IdToken | undefined> {
public async getDecodedIdToken(sessionId?: string): Promise<IdToken | undefined> {
await this._validateMethod();

return this._client?.getDecodedIdToken();
return this._client?.getDecodedIdToken(sessionId);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,7 @@ export const MainThreadClient = async (

const getUser = async (): Promise<User> => _authenticationHelper.getUser();

const getDecodedIdToken = async (): Promise<IdToken> => _authenticationHelper.getDecodedIdToken();
const getDecodedIdToken = async (sessionId?: string): Promise<IdToken> => _authenticationHelper.getDecodedIdToken(sessionId);

const getCrypto = async (): Promise<IsomorphicCrypto> => _authenticationHelper.getCrypto();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -706,7 +706,7 @@ export const WebWorkerClient = async (
});
};

const getDecodedIdToken = (): Promise<IdToken> => {
const getDecodedIdToken = (sessionId?: string): Promise<IdToken> => {
const message: Message<null> = {
type: GET_DECODED_ID_TOKEN,
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -659,8 +659,8 @@ export class AuthenticationHelper<T extends MainThreadClientConfig | WebWorkerCl
return this._authenticationClient.getUser();
}

public async getDecodedIdToken(): Promise<IdToken> {
return this._authenticationClient.getDecodedIdToken();
public async getDecodedIdToken(sessionId?: string): Promise<IdToken> {
return this._authenticationClient.getDecodedIdToken(sessionId);
}

public async getDecodedIDPIDToken(): Promise<IdToken> {
Expand Down
4 changes: 2 additions & 2 deletions packages/browser/src/__legacy__/models/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ export interface MainThreadClientInterface {
refreshAccessToken(): Promise<User>;
revokeAccessToken(): Promise<boolean>;
getUser(): Promise<User>;
getDecodedIdToken(): Promise<IdToken>;
getDecodedIdToken(sessionId?: string): Promise<IdToken>;
getCrypto(): Promise<IsomorphicCrypto>;
getConfigData(): Promise<AuthClientConfig<MainThreadClientConfig>>;
getIdToken(): Promise<string>;
Expand Down Expand Up @@ -96,7 +96,7 @@ export interface WebWorkerClientInterface {
getOpenIDProviderEndpoints(): Promise<OIDCEndpoints>;
getUser(): Promise<User>;
getConfigData(): Promise<AuthClientConfig<WebWorkerClientConfig>>;
getDecodedIdToken(): Promise<IdToken>;
getDecodedIdToken(sessionId?: string): Promise<IdToken>;
getDecodedIDPIDToken(): Promise<IdToken>;
getCrypto(): Promise<IsomorphicCrypto>;
getIdToken(): Promise<string>;
Expand Down
2 changes: 1 addition & 1 deletion packages/browser/src/__legacy__/models/web-worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export interface WebWorkerCoreInterface {
refreshAccessToken(): Promise<User>;
revokeAccessToken(): Promise<boolean>;
getUser(): Promise<User>;
getDecodedIdToken(): Promise<IdToken>;
getDecodedIdToken(sessionId?: string): Promise<IdToken>;
getDecodedIDPIDToken(): Promise<IdToken>;
getCrypto(): Promise<IsomorphicCrypto>;
getIdToken(): Promise<string>;
Expand Down
4 changes: 2 additions & 2 deletions packages/browser/src/__legacy__/worker/worker-core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,8 +166,8 @@ export const WebWorkerCore = async (
return _authenticationHelper.getUser();
};

const getDecodedIdToken = async (): Promise<IdToken> => {
return _authenticationHelper.getDecodedIdToken();
const getDecodedIdToken = async (sessionId?: string): Promise<IdToken> => {
return _authenticationHelper.getDecodedIdToken(sessionId);
};

const getCrypto = async (): Promise<IsomorphicCrypto> => {
Expand Down
7 changes: 7 additions & 0 deletions packages/browser/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,10 @@ export {default as AsgardeoBrowserClient} from './AsgardeoBrowserClient';

// Re-export everything from the JavaScript package
export * from '@asgardeo/javascript';

export {
detectThemeMode,
createClassObserver,
createMediaQueryListener,
BrowserThemeDetection,
} from './theme/themeDetection';
134 changes: 134 additions & 0 deletions packages/browser/src/theme/themeDetection.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
/**
* Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com).
*
* WSO2 LLC. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import {ThemeDetection, ThemeMode} from '@asgardeo/javascript';

/**
* Extended theme detection config that includes DOM-specific options
*/
export interface BrowserThemeDetection extends ThemeDetection {
/**
* The element to observe for class changes
* @default document.documentElement (html element)
*/
targetElement?: HTMLElement;
}

/**
* Detects the current theme mode based on the specified method
*/
export const detectThemeMode = (mode: ThemeMode, config: BrowserThemeDetection = {}): 'light' | 'dark' => {
const {
darkClass = 'dark',
lightClass = 'light',
targetElement = typeof document !== 'undefined' ? document.documentElement : null,
} = config;

if (mode === 'light') return 'light';
if (mode === 'dark') return 'dark';

if (mode === 'system') {
if (typeof window !== 'undefined' && window.matchMedia) {
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
}
return 'light';
}

if (mode === 'class') {
if (!targetElement) {
console.warn('ThemeDetection: targetElement is required for class-based detection, falling back to light mode');
return 'light';
}

const classList = targetElement.classList;

// Check for explicit dark class first
if (classList.contains(darkClass)) {
return 'dark';
}

// Check for explicit light class
if (classList.contains(lightClass)) {
return 'light';
}

// If neither class is present, default to light
return 'light';
}

return 'light';
};

/**
* Creates a MutationObserver to watch for class changes on the target element
*/
export const createClassObserver = (
targetElement: HTMLElement,
callback: (isDark: boolean) => void,
config: BrowserThemeDetection = {},
): MutationObserver => {
const {darkClass = 'dark', lightClass = 'light'} = config;

const observer = new MutationObserver(mutations => {
mutations.forEach(mutation => {
if (mutation.type === 'attributes' && mutation.attributeName === 'class') {
const classList = targetElement.classList;

if (classList.contains(darkClass)) {
callback(true);
} else if (classList.contains(lightClass)) {
callback(false);
}
// If neither class is present, we don't trigger the callback
// to avoid unnecessary re-renders
}
});
});

observer.observe(targetElement, {
attributes: true,
attributeFilter: ['class'],
});

return observer;
};

/**
* Creates a media query listener for system theme changes
*/
export const createMediaQueryListener = (callback: (isDark: boolean) => void): MediaQueryList | null => {
if (typeof window === 'undefined' || !window.matchMedia) {
return null;
}

const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');

const handleChange = (e: MediaQueryListEvent) => {
callback(e.matches);
};

// Modern browsers
if (mediaQuery.addEventListener) {
mediaQuery.addEventListener('change', handleChange);
} else {
// Fallback for older browsers
mediaQuery.addListener(handleChange);
}

return mediaQuery;
};
10 changes: 6 additions & 4 deletions packages/javascript/src/AsgardeoJavaScriptClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,18 +34,20 @@ abstract class AsgardeoJavaScriptClient<T = Config> implements AsgardeoClient<T>

abstract initialize(config: T): Promise<boolean>;

abstract getUser(): Promise<User>;
abstract getUser(options?: any): Promise<User>;

abstract getOrganizations(): Promise<Organization[]>;
abstract getOrganizations(options?: any): Promise<Organization[]>;

abstract getCurrentOrganization(): Promise<Organization | null>;
abstract getCurrentOrganization(sessionId?: string): Promise<Organization | null>;

abstract getUserProfile(): Promise<UserProfile>;
abstract getUserProfile(options?: any): Promise<UserProfile>;

abstract isLoading(): boolean;

abstract isSignedIn(): Promise<boolean>;

abstract updateUserProfile(payload: any, userId?: string): Promise<User>;

abstract getConfiguration(): T;

abstract signIn(
Expand Down
Loading
Loading