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
51 changes: 50 additions & 1 deletion example/reactweb/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import authgear, {
Page,
WebContainerDelegate,
SessionState,
LinkOAuthOptions,
} from "@authgear/web";
import "./App.css";

Expand Down Expand Up @@ -66,6 +67,8 @@ function getOAuthState(): OAuthState | undefined {
return "change_phone";
case "change_username":
return "change_username";
case "link_oauth":
return "link_oauth";
}
return undefined;
}
Expand All @@ -81,7 +84,8 @@ type OAuthState =
| "add_username"
| "change_email"
| "change_phone"
| "change_username";
| "change_username"
| "link_oauth";

function ShowError(props: { error: unknown }) {
const { error } = props;
Expand Down Expand Up @@ -123,6 +127,7 @@ function Root() {
const [page, setPage] = useState<string>();
const [authenticationFlowGroup, setAuthenticationflowGroup] =
useState<string>("");
const [oauthProviderAlias, setOauthProviderAlias] = useState<string>("");

const [error, setError] = useState<unknown>(null);
const [userInfo, setUserInfo] = useState<UserInfo | null>(null);
Expand Down Expand Up @@ -323,6 +328,25 @@ function Root() {
[userInfo]
);

const onClickLinkOAuth = useCallback(
(e: React.MouseEvent<HTMLElement>) => {
e.preventDefault();
e.stopPropagation();
if (oauthProviderAlias === "") {
setError(new Error("OAuth Provider Alias is required"));
return;
}
authgear
.startLinkOAuth({
redirectURI: makeRedirectURI(),
state: "link_oauth",
oauthProviderAlias,
})
.catch((err) => setError(err));
},
[oauthProviderAlias]
);

const onClickChangeUsername = useCallback(
(e: React.MouseEvent<HTMLElement>) => {
e.preventDefault();
Expand Down Expand Up @@ -664,6 +688,23 @@ function Root() {
>
Change Username
</button>
<label className="label">
OAuth Provider Alias (required for Link OAuth)
<input
className="input"
type="text"
placeholder="e.g. google"
value={oauthProviderAlias}
onChange={(e) => setOauthProviderAlias(e.currentTarget.value)}
/>
</label>
<button
className="button"
type="button"
onClick={onClickLinkOAuth}
>
Link OAuth
</button>
<button className="button" type="button" onClick={onClickSignOut}>
Sign out
</button>
Expand Down Expand Up @@ -801,6 +842,14 @@ function AuthRedirect() {
(err) => setError(err)
);
break;
case "link_oauth":
authgear.finishLinkOAuth().then(
(_) => {
navigate("/");
},
(err) => setError(err)
);
break;
default:
throw new Error("unknown oauth state: " + oauthState);
}
Expand Down
7 changes: 6 additions & 1 deletion packages/authgear-core/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,8 @@ export interface _OIDCAuthenticationRequest {
| "add_username"
| "change_email"
| "change_phone"
| "change_username";
| "change_username"
| "link_oauth";
xSettingsActionQuery?: _SettingsActionQuery;
authenticationFlowGroup?: string;
clientID?: string;
Expand Down Expand Up @@ -572,6 +573,10 @@ export enum SettingsAction {
* Change username in Authgear settings page.
*/
ChangeUsername = "change_username",
/**
* Link an OAuth provider in Authgear settings page.
*/
LinkOAuth = "link_oauth",
}

/**
Expand Down
21 changes: 21 additions & 0 deletions packages/authgear-web/src/container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import {
ReauthenticateResult,
SettingsActionOptions,
_InternalSettingsActionOptions,
LinkOAuthOptions,
} from "./types";

/**
Expand Down Expand Up @@ -669,6 +670,26 @@ export class WebContainer {
return this.finishSettingsAction();
}

/**
* Start settings action "link_oauth" by redirecting to the authorization endpoint.
*
* @public
*/
async startLinkOAuth(options: LinkOAuthOptions): Promise<void> {
await this.startSettingsAction(SettingsAction.LinkOAuth, options);
}

/**
* Finish settings action "link_oauth".
*
* It may reject with OAuthError.
*
* @public
*/
async finishLinkOAuth(): Promise<void> {
return this.finishSettingsAction();
}

/**
* Finish promote anonymous user.
*
Expand Down
13 changes: 13 additions & 0 deletions packages/authgear-web/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -185,11 +185,24 @@ export interface SettingsActionOptions {
uiLocales?: string[];
}

/**
* Options for connecting an OAuth provider via settings action.
* @public
*/
export interface LinkOAuthOptions extends SettingsActionOptions {
/**
* The alias of the OAuth provider to link,
* as configured in Authgear Portal under Social / Enterprise Login.
*/
oauthProviderAlias: string;
}

/**
* @internal
*/
export interface _InternalSettingsActionOptions extends SettingsActionOptions {
qLoginID?: string;
oauthProviderAlias?: string;
}

/**
Expand Down
Loading