Skip to content
Open
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
78 changes: 46 additions & 32 deletions src/state/KindeProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,25 +57,25 @@ type EventTypes = {
(
event: AuthEvent.tokenRefreshed,
state: RefreshTokenResult,
context: KindeContextProps,
context: KindeContextProps
): void;
(
event: AuthEvent,
state: Record<string, unknown>,
context: KindeContextProps,
context: KindeContextProps
): void;
};

type KindeCallbacks = {
onSuccess?: (
user: UserProfile,
state: Record<string, unknown>,
context: KindeContextProps,
context: KindeContextProps
) => void;
onError?: (
props: ErrorProps,
state: Record<string, string>,
context: KindeContextProps,
context: KindeContextProps
) => void;
onEvent?: EventTypes;
};
Expand All @@ -85,6 +85,7 @@ type KindeProviderProps = {
children: React.ReactNode;
clientId: string;
domain: string;
authorizationEndpoint?: string;
/**
* Use localstorage for refresh token.
*
Expand Down Expand Up @@ -124,6 +125,7 @@ export const KindeProvider = ({
clientId,
children,
domain,
authorizationEndpoint,
useInsecureForRefreshToken = false,
redirectUri,
callbacks = {},
Expand Down Expand Up @@ -158,7 +160,7 @@ export const KindeProvider = ({

const login = useCallback(
async (
options: LoginMethodParams & { state?: Record<string, string> } = {},
options: LoginMethodParams & { state?: Record<string, string> } = {}
) => {
const optionsState: Record<string, string> = options.state || {};

Expand All @@ -173,28 +175,40 @@ export const KindeProvider = ({
JSON.stringify({
kinde: { event: AuthEvent.login },
...optionsState,
}),
})
),
redirectURL: getRedirectUrl(options.redirectURL || redirectUri),
};

const domain = (await storeState.memoryStorage.getSessionItem(
storeState.LocalKeys.domain,
storeState.LocalKeys.domain
)) as string;

const authUrl = await generateAuthUrl(
domain,
IssuerRouteTypes.login,
authProps,
authProps
);
document.location = authUrl.url.toString();
let redirectUrl = "";
if (authorizationEndpoint) {
// override just the path, keep the query string
const custom = new URL(authUrl.url.toString());
// ensure it’s a path, not a full URL
custom.pathname = authorizationEndpoint.startsWith("/")
? authorizationEndpoint
: `/${authorizationEndpoint}`;
redirectUrl = custom.toString();
} else {
redirectUrl = authUrl.url.toString();
}
document.location = redirectUrl;
},
[audience, clientId, redirectUri],
[audience, clientId, redirectUri, authorizationEndpoint]
);

const register = useCallback(
async (
options: LoginMethodParams & { state?: Record<string, string> } = {},
options: LoginMethodParams & { state?: Record<string, string> } = {}
) => {
const optionsState: Record<string, string> = options.state || {};

Expand All @@ -206,28 +220,28 @@ export const KindeProvider = ({
JSON.stringify({
kinde: { event: AuthEvent.register },
...optionsState,
}),
})
),
supportsReauth: true,
audience: (await storeState.memoryStorage.getSessionItem(
storeState.LocalKeys.audience,
storeState.LocalKeys.audience
)) as string,
clientId: (await storeState.memoryStorage.getSessionItem(
storeState.LocalKeys.clientId,
storeState.LocalKeys.clientId
)) as string,
redirectURL: getRedirectUrl(options?.redirectURL || redirectUri),
prompt: PromptTypes.create,
};

try {
const domain = (await storeState.memoryStorage.getSessionItem(
storeState.LocalKeys.domain,
storeState.LocalKeys.domain
)) as string;

const authUrl = await generateAuthUrl(
domain,
IssuerRouteTypes.register,
authProps,
authProps
);
document.location = authUrl.url.toString();
} catch (error) {
Expand All @@ -238,17 +252,17 @@ export const KindeProvider = ({
errorDescription: String(error),
},
{},
contextValue,
contextValue
);
}
},
[redirectUri],
[redirectUri]
);

const logout = useCallback(async (options?: string | LogoutOptions) => {
try {
const domain = (await storeState.memoryStorage.getSessionItem(
storeState.LocalKeys.domain,
storeState.LocalKeys.domain
)) as string;

const params = new URLSearchParams();
Expand Down Expand Up @@ -286,7 +300,7 @@ export const KindeProvider = ({
errorDescription: String(error),
},
{},
contextValue,
contextValue
);
}
}, []);
Expand All @@ -305,19 +319,19 @@ export const KindeProvider = ({
getAccessToken: async (): Promise<string | undefined> => {
const storage = getActiveStorage();
return (await storage?.getSessionItem(
StorageKeys.accessToken,
StorageKeys.accessToken
)) as string;
},
/** @deprecated use `getAccessToken` instead */
getToken: async (): Promise<string | undefined> => {
const storage = getActiveStorage();
return (await storage?.getSessionItem(
StorageKeys.accessToken,
StorageKeys.accessToken
)) as string;
},

getClaim: async <T, V = string | number | string[]>(
keyName: keyof T,
keyName: keyof T
): Promise<{ name: keyof T; value: V } | null> => {
return getClaim<T, V>(keyName);
},
Expand All @@ -334,7 +348,7 @@ export const KindeProvider = ({
return await getCurrentOrganization();
},
getFlag: async <T = string | number | boolean,>(
name: string,
name: string
): Promise<T | null> => {
return await getFlag<T>(name);
},
Expand All @@ -346,7 +360,7 @@ export const KindeProvider = ({
},

getPermission: async <T = string,>(
permissionKey: T,
permissionKey: T
): Promise<PermissionAccess> => {
return await getPermission(permissionKey);
},
Expand Down Expand Up @@ -377,7 +391,7 @@ export const KindeProvider = ({
mergedCallbacks.onEvent(AuthEvent.tokenRefreshed, data, contextValue);
}
},
[mergedCallbacks, contextValue],
[mergedCallbacks, contextValue]
);

const handleFocus = useCallback(() => {
Expand Down Expand Up @@ -442,7 +456,7 @@ export const KindeProvider = ({
try {
returnedState = JSON.parse(decoded);
kindeState = Object.assign(
returnedState.kinde || { event: PromptTypes.login },
returnedState.kinde || { event: PromptTypes.login }
);
} catch (error) {
console.error("Error parsing state:", error);
Expand All @@ -452,14 +466,14 @@ export const KindeProvider = ({
errorDescription: String(error),
},
{},
contextValue,
contextValue
);
returnedState = {} as StateWithKinde;
kindeState = { event: AuthEvent.login };
}
try {
const redirectURL = (await storeState.memoryStorage.getSessionItem(
storeState.LocalKeys.redirectUri,
storeState.LocalKeys.redirectUri
)) as string;

const codeResponse = await exchangeAuthCode({
Expand All @@ -481,7 +495,7 @@ export const KindeProvider = ({
...returnedState,
kinde: undefined,
},
contextValue,
contextValue
);
if (mergedCallbacks.onEvent) {
mergedCallbacks.onEvent(
Expand All @@ -490,7 +504,7 @@ export const KindeProvider = ({
...returnedState,
kinde: undefined,
},
contextValue,
contextValue
);
}
}
Expand All @@ -501,7 +515,7 @@ export const KindeProvider = ({
errorDescription: codeResponse.error,
},
returnedState,
contextValue,
contextValue
);
}
} finally {
Expand Down