nocal-auth-sdk 0.2.0 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +3 -2
- package/dist/index.js +63 -21
- package/dist/types.d.ts +6 -2
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -7,16 +7,17 @@ export declare class NocalAuthSDK {
|
|
|
7
7
|
private currentUser;
|
|
8
8
|
constructor(config: NocalClientConfig);
|
|
9
9
|
/**
|
|
10
|
-
* Mở Popup UI Đăng nhập & Ủy quyền OAuth 2.0 với PKCE
|
|
10
|
+
* Mở Popup UI Đăng nhập & Ủy quyền chuẩn Supabase Native OAuth 2.0 với PKCE
|
|
11
11
|
*/
|
|
12
12
|
signInWithNocal(req?: OAuthLoginReq): Promise<{
|
|
13
13
|
user: NocalUser;
|
|
14
14
|
session: NocalSession;
|
|
15
15
|
}>;
|
|
16
|
-
|
|
16
|
+
exchangeCodeForToken(code: string, codeVerifier: string): Promise<NocalSession>;
|
|
17
17
|
private fetchUserInfo;
|
|
18
18
|
getUser(): Promise<NocalUser | null>;
|
|
19
19
|
getSession(): Promise<NocalSession | null>;
|
|
20
20
|
signOut(): Promise<void>;
|
|
21
21
|
}
|
|
22
|
+
export { NocalAuthSDK as NocalAuth };
|
|
22
23
|
export * from "./types";
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const DEFAULT_AUTH_SERVER_URL = "
|
|
1
|
+
const DEFAULT_AUTH_SERVER_URL = "https://hldymiruucsqqzicnwdv.supabase.co";
|
|
2
2
|
// Helper for PKCE crypto
|
|
3
3
|
function base64URLEncode(buffer) {
|
|
4
4
|
let binary = "";
|
|
@@ -45,13 +45,13 @@ export class NocalAuthSDK {
|
|
|
45
45
|
}
|
|
46
46
|
}
|
|
47
47
|
/**
|
|
48
|
-
* Mở Popup UI Đăng nhập & Ủy quyền OAuth 2.0 với PKCE
|
|
48
|
+
* Mở Popup UI Đăng nhập & Ủy quyền chuẩn Supabase Native OAuth 2.0 với PKCE
|
|
49
49
|
*/
|
|
50
50
|
async signInWithNocal(req) {
|
|
51
51
|
const state = req?.state || generateRandomString(16);
|
|
52
52
|
const codeVerifier = generateRandomString(32);
|
|
53
53
|
const codeChallenge = await generateCodeChallenge(codeVerifier);
|
|
54
|
-
const authUrl = new URL(`${this.authServerUrl}/oauth/authorize`);
|
|
54
|
+
const authUrl = new URL(`${this.authServerUrl}/auth/v1/oauth/authorize`);
|
|
55
55
|
authUrl.searchParams.set("client_id", this.clientId);
|
|
56
56
|
authUrl.searchParams.set("redirect_uri", this.redirectUri);
|
|
57
57
|
authUrl.searchParams.set("response_type", "code");
|
|
@@ -60,8 +60,12 @@ export class NocalAuthSDK {
|
|
|
60
60
|
authUrl.searchParams.set("code_challenge_method", "S256");
|
|
61
61
|
const width = 480;
|
|
62
62
|
const height = 680;
|
|
63
|
-
const left = typeof window !== "undefined"
|
|
64
|
-
|
|
63
|
+
const left = typeof window !== "undefined"
|
|
64
|
+
? window.screenX + (window.outerWidth - width) / 2
|
|
65
|
+
: 0;
|
|
66
|
+
const top = typeof window !== "undefined"
|
|
67
|
+
? window.screenY + (window.outerHeight - height) / 2
|
|
68
|
+
: 0;
|
|
65
69
|
const popup = window.open(authUrl.toString(), "NocalAuthPopup", `width=${width},height=${height},left=${left},top=${top},status=yes,scrollbars=yes`);
|
|
66
70
|
if (!popup) {
|
|
67
71
|
throw new Error("POPUP_BLOCKED");
|
|
@@ -72,7 +76,9 @@ export class NocalAuthSDK {
|
|
|
72
76
|
if (event.origin !== allowedOrigin)
|
|
73
77
|
return;
|
|
74
78
|
const data = event.data;
|
|
75
|
-
if (!data ||
|
|
79
|
+
if (!data ||
|
|
80
|
+
(data.type !== "NOCAL_OAUTH_CODE" &&
|
|
81
|
+
data.type !== "NOCAL_OAUTH_ERROR")) {
|
|
76
82
|
return;
|
|
77
83
|
}
|
|
78
84
|
window.removeEventListener("message", messageListener);
|
|
@@ -95,7 +101,6 @@ export class NocalAuthSDK {
|
|
|
95
101
|
}
|
|
96
102
|
try {
|
|
97
103
|
popup.close();
|
|
98
|
-
// Đổi code lấy token
|
|
99
104
|
const session = await this.exchangeCodeForToken(code, codeVerifier);
|
|
100
105
|
const user = await this.fetchUserInfo(session.access_token);
|
|
101
106
|
this.currentSession = session;
|
|
@@ -117,6 +122,40 @@ export class NocalAuthSDK {
|
|
|
117
122
|
window.removeEventListener("message", messageListener);
|
|
118
123
|
reject(new Error("POPUP_CLOSED_BY_USER"));
|
|
119
124
|
}
|
|
125
|
+
else {
|
|
126
|
+
try {
|
|
127
|
+
const popupUrl = new URL(popup.location.href);
|
|
128
|
+
if (popupUrl.origin === new URL(this.redirectUri).origin) {
|
|
129
|
+
const code = popupUrl.searchParams.get("code");
|
|
130
|
+
const error = popupUrl.searchParams.get("error");
|
|
131
|
+
if (code || error) {
|
|
132
|
+
clearInterval(checkClosedTimer);
|
|
133
|
+
window.removeEventListener("message", messageListener);
|
|
134
|
+
popup.close();
|
|
135
|
+
if (error) {
|
|
136
|
+
reject(new Error(error));
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
if (code) {
|
|
140
|
+
this.exchangeCodeForToken(code, codeVerifier)
|
|
141
|
+
.then(async (session) => {
|
|
142
|
+
const user = await this.fetchUserInfo(session.access_token);
|
|
143
|
+
this.currentSession = session;
|
|
144
|
+
this.currentUser = user;
|
|
145
|
+
if (typeof window !== "undefined") {
|
|
146
|
+
localStorage.setItem("nocal_auth_session", JSON.stringify({ session, user }));
|
|
147
|
+
}
|
|
148
|
+
resolve({ user, session });
|
|
149
|
+
})
|
|
150
|
+
.catch(reject);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
catch (e) {
|
|
156
|
+
// Cross-origin check
|
|
157
|
+
}
|
|
158
|
+
}
|
|
120
159
|
}
|
|
121
160
|
catch (e) {
|
|
122
161
|
// ignore
|
|
@@ -125,25 +164,27 @@ export class NocalAuthSDK {
|
|
|
125
164
|
});
|
|
126
165
|
}
|
|
127
166
|
async exchangeCodeForToken(code, codeVerifier) {
|
|
128
|
-
const
|
|
167
|
+
const params = new URLSearchParams();
|
|
168
|
+
params.set("grant_type", "authorization_code");
|
|
169
|
+
params.set("client_id", this.clientId);
|
|
170
|
+
params.set("redirect_uri", this.redirectUri);
|
|
171
|
+
params.set("code", code);
|
|
172
|
+
params.set("code_verifier", codeVerifier); // PKCE xác thực thay cho secret
|
|
173
|
+
const response = await fetch(`${this.authServerUrl}/auth/v1/oauth/token`, {
|
|
129
174
|
method: "POST",
|
|
130
|
-
headers: {
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
client_id: this.clientId,
|
|
135
|
-
redirect_uri: this.redirectUri,
|
|
136
|
-
code_verifier: codeVerifier,
|
|
137
|
-
}),
|
|
175
|
+
headers: {
|
|
176
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
177
|
+
},
|
|
178
|
+
body: params.toString(),
|
|
138
179
|
});
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
throw new Error(
|
|
180
|
+
if (!response.ok) {
|
|
181
|
+
const errorData = await response.json();
|
|
182
|
+
throw new Error(`Supabase Auth Error: ${errorData.error_description || errorData.error}`);
|
|
142
183
|
}
|
|
143
|
-
return
|
|
184
|
+
return (await response.json());
|
|
144
185
|
}
|
|
145
186
|
async fetchUserInfo(accessToken) {
|
|
146
|
-
const res = await fetch(`${this.authServerUrl}/
|
|
187
|
+
const res = await fetch(`${this.authServerUrl}/auth/v1/oauth/userinfo`, {
|
|
147
188
|
headers: {
|
|
148
189
|
Authorization: `Bearer ${accessToken}`,
|
|
149
190
|
},
|
|
@@ -168,4 +209,5 @@ export class NocalAuthSDK {
|
|
|
168
209
|
}
|
|
169
210
|
}
|
|
170
211
|
}
|
|
212
|
+
export { NocalAuthSDK as NocalAuth };
|
|
171
213
|
export * from "./types";
|
package/dist/types.d.ts
CHANGED
|
@@ -2,9 +2,12 @@ export interface NocalClientConfig {
|
|
|
2
2
|
clientId: string;
|
|
3
3
|
redirectUri: string;
|
|
4
4
|
authServerUrl?: string;
|
|
5
|
+
storageKey?: string;
|
|
5
6
|
}
|
|
6
7
|
export interface OAuthLoginReq {
|
|
7
8
|
state?: string;
|
|
9
|
+
provider?: string;
|
|
10
|
+
redirectTo?: string;
|
|
8
11
|
}
|
|
9
12
|
export interface NocalUser {
|
|
10
13
|
sub: string;
|
|
@@ -12,12 +15,13 @@ export interface NocalUser {
|
|
|
12
15
|
phone?: string;
|
|
13
16
|
email_confirmed?: boolean;
|
|
14
17
|
phone_confirmed?: boolean;
|
|
15
|
-
user_metadata?: Record<string,
|
|
16
|
-
[key: string]:
|
|
18
|
+
user_metadata?: Record<string, unknown>;
|
|
19
|
+
[key: string]: unknown;
|
|
17
20
|
}
|
|
18
21
|
export interface NocalSession {
|
|
19
22
|
access_token: string;
|
|
20
23
|
refresh_token: string;
|
|
21
24
|
token_type: string;
|
|
22
25
|
expires_in: number;
|
|
26
|
+
expires_at?: number;
|
|
23
27
|
}
|