Skip to content

Commit

Permalink
✨ feat: oauth oidc popup-based redirect (#188)
Browse files Browse the repository at this point in the history
  • Loading branch information
rustin01 authored Oct 29, 2024
1 parent 8f5fcbc commit 09c0133
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 6 deletions.
72 changes: 72 additions & 0 deletions apps/wallet/src/utils/auth/oauth2-oidc-window.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
class OAuth2OidcWindow {
public readonly url: string;
public readonly redirectOrigin: string;

private window: WindowProxy | null = null
private promise: Promise<boolean> | null = null
private _iid: number | null = null;

constructor(url: string, redirectOrigin: string) {
this.url = url;
this.redirectOrigin = redirectOrigin;
}

open() {
const { url } = this;
this.window = window.open(url, 'oauth2-oidc', 'popup=1,width=800,height=600');
}

close() {
this.cancel();
this.window?.close();
}

poll() {
this.promise = new Promise((resolve, reject) => {
this._iid = window.setInterval(() => {
try {
const popup = this.window;
if (!popup || popup.closed !== false) {
this.close();
reject(new Error('The popup was closed by user'));
return;
}
if (popup.location.origin !== this.redirectOrigin) {
return;
}
resolve(true);
this.close();
} catch (error) {
/*
* Ignore DOMException: Blocked a frame with origin from accessing a
* cross-origin frame.
*/
}
}, 500);
});
}

cancel() {
if (this._iid) {
window.clearInterval(this._iid);
this._iid = null;
}
}

then(onSuccess: () => void) {
return this.promise?.then(onSuccess);
}

catch(onError: (err: Error) => void) {
return this.promise?.catch(onError);
}

static open(url: string, redirectOrigin: string) {
const popup = new OAuth2OidcWindow(url, redirectOrigin);
popup.open();
popup.poll();
return popup;
}
}

export default OAuth2OidcWindow;
16 changes: 13 additions & 3 deletions apps/wallet/src/utils/auth/providers/google.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import OAuth2OidcWindow from "../oauth2-oidc-window";
import { IAuthenticateProvider } from "../types";
import { AuthenticatorType } from "@delandlabs/hibit-id-sdk";

Expand All @@ -7,8 +8,17 @@ export class GoogleAuthenticateProvider implements IAuthenticateProvider {
public readonly type = AuthenticatorType.Google

public authenticate: (launchParams?: any) => Promise<any> = async (launchParams?: string) => {
window.location.href =
`${AUTH_SERVER_URL}id/login/google?returnUrl=${encodeURIComponent(`${location.origin}/oidc-login`)}`
return
const loginUrl = `${AUTH_SERVER_URL}id/login/google?returnUrl=${encodeURIComponent(`${location.origin}/oidc-login`)}`
await new Promise((resolve, reject) => {
OAuth2OidcWindow
.open(loginUrl, location.origin)
.then(() => {
location.href = `${location.origin}/oidc-login`
resolve(true)
})
?.catch((reason) => {
reject(reason)
})
})
}
}
16 changes: 13 additions & 3 deletions apps/wallet/src/utils/auth/providers/x.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import OAuth2OidcWindow from "../oauth2-oidc-window";
import { IAuthenticateProvider } from "../types";
import { AuthenticatorType } from "@delandlabs/hibit-id-sdk";

Expand All @@ -7,8 +8,17 @@ export class XAuthenticateProvider implements IAuthenticateProvider {
public readonly type = AuthenticatorType.X

public authenticate: (launchParams?: any) => Promise<any> = async (launchParams?: string) => {
window.location.href =
`${AUTH_SERVER_URL}id/login/twitter?returnUrl=${encodeURIComponent(`${location.origin}/oidc-login`)}`
return
const loginUrl = `${AUTH_SERVER_URL}id/login/twitter?returnUrl=${encodeURIComponent(`${location.origin}/oidc-login`)}`
await new Promise((resolve, reject) => {
OAuth2OidcWindow
.open(loginUrl, location.origin)
.then(() => {
location.href = `${location.origin}/oidc-login`
resolve(true)
})
?.catch((reason) => {
reject(reason)
})
})
}
}

0 comments on commit 09c0133

Please sign in to comment.