Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add getLoginUrl function #4

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
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
16 changes: 16 additions & 0 deletions packages/auth/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,22 @@ Provides the `UserSession` object if the user is authenticated.

## Methods

### getLoginUrl

▸ `Optional` **getLoginUrl**(`opts?`): `Promise<string>`

Function to generate the login URL.

#### Parameters

| Name | Type |
| :------ | :------ |
| `opts?` | [`LoginOptions`](#LoginOptions) |

#### Returns

`Promise<string>`

### login

▸ `Optional` **login**(`opts?`): `void`
Expand Down
31 changes: 15 additions & 16 deletions packages/auth/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,6 @@ interface IdpResponse {
code: string;
}

interface IdpErrorResponse {
error: string;
error_description: string;
}

function isTokenResponse(args: unknown): args is TokenResponse {
return isObject(args) &&
typeof args.access_token === 'string' &&
Expand All @@ -85,12 +80,6 @@ function isIdpResponse(args: unknown): args is IdpResponse {
return isObject(args) && typeof args.code === 'string';
}

function isIdpErrorResponse(args: unknown): args is IdpErrorResponse {
return isObject(args) &&
typeof args.error === 'string' &&
typeof args.error_description === 'string';
}

function isString(arg: unknown): arg is string {
return typeof arg === 'string';
}
Expand Down Expand Up @@ -130,6 +119,8 @@ export interface UserInfo {
* The user context object is returned by the `useUser` hook.
*/
export interface UserContext {
/** Function to generate the login URL. */
getLoginUrl?: (opts?: LoginOptions) => Promise<string>;
/** Provides the `UserInfo` object if the user is authenticated. */
info?: UserInfo;
/** Provides the `UserSession` object if the user is authenticated. */
Expand Down Expand Up @@ -207,9 +198,9 @@ export function UserContextProvider({

const [userInfo, setUserInfo] = useState<UserInfo>();

const login = useCallback(async (
const getLoginUrl = useCallback(async (
{ entrypoint, redirect = true }: LoginOptions = {}
): Promise<void> => {
) => {
const newKey = await generateVerifier();
const encodedKey = base64encode(newKey);
setKey(encodedKey);
Expand All @@ -219,8 +210,7 @@ export function UserContextProvider({
}
const challenge = base64encode(await sha256(encodedKey));

document.location.href =
`https://${idpHost}/oauth2/authorize?` +
return `https://${idpHost}/oauth2/authorize?` +
querystring.stringify({
client_id: clientId,
domain_hint: domainHint,
Expand All @@ -233,6 +223,14 @@ export function UserContextProvider({
});
}, [setKey, idpHost, clientId, domainHint, redirectUri, setEntrypoint, prompt]);

const login = useCallback(async (
options: LoginOptions = {}
): Promise<void> => {
const loginUrl = await getLoginUrl(options);

document.location.href = loginUrl;
}, [getLoginUrl]);

const logout = useCallback((): void => {
clearSession();
setUserInfo(undefined);
Expand Down Expand Up @@ -359,13 +357,14 @@ export function UserContextProvider({
<UserContext.Provider
value={useMemo(() => {
return {
getLoginUrl,
info: userInfo,
session,
login,
logout,
authHeader,
};
}, [session, userInfo, login, logout, authHeader])}
}, [getLoginUrl, userInfo, session, login, logout, authHeader])}
>{!autoLogin || userInfo ? children : null}</UserContext.Provider>
);
}
Expand Down