@idealyst/oauth-client 1.2.9 → 1.2.12
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.mts +32 -12
- package/dist/index.d.ts +32 -12
- package/dist/index.js +15 -21
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +15 -21
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/index.native.ts +3 -3
- package/src/index.web.ts +3 -3
- package/src/oauth-client.native.ts +35 -44
- package/src/oauth-client.web.ts +33 -34
- package/src/types.ts +31 -9
package/dist/index.d.mts
CHANGED
|
@@ -1,25 +1,45 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Raw callback parameters from OAuth redirect
|
|
3
|
+
* Contains all query parameters returned by the OAuth provider
|
|
4
|
+
*/
|
|
5
|
+
type OAuthCallbackParams = Record<string, string | undefined>;
|
|
6
|
+
/**
|
|
7
|
+
* Default OAuth result with standard code and state
|
|
8
|
+
*/
|
|
6
9
|
interface OAuthResult {
|
|
7
10
|
code: string;
|
|
8
11
|
state?: string;
|
|
9
12
|
}
|
|
10
|
-
|
|
11
|
-
|
|
13
|
+
/**
|
|
14
|
+
* OAuth configuration options
|
|
15
|
+
*/
|
|
16
|
+
interface OAuthConfig<T = OAuthResult> {
|
|
17
|
+
oauthUrl: string;
|
|
18
|
+
redirectUrl: string;
|
|
19
|
+
additionalParameters?: Record<string, string>;
|
|
20
|
+
/**
|
|
21
|
+
* Optional transformer to convert raw callback params to desired type
|
|
22
|
+
* If not provided, returns all callback params as-is (typed as T)
|
|
23
|
+
*/
|
|
24
|
+
transformCallback?: (params: OAuthCallbackParams) => T;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* OAuth client interface with generic result type
|
|
28
|
+
* @template T - The type returned from authorize(), defaults to OAuthResult
|
|
29
|
+
*/
|
|
30
|
+
interface OAuthClient<T = OAuthResult> {
|
|
31
|
+
authorize(): Promise<T>;
|
|
12
32
|
}
|
|
13
33
|
|
|
14
|
-
declare class WebOAuthClient implements OAuthClient {
|
|
34
|
+
declare class WebOAuthClient<T = OAuthResult> implements OAuthClient<T> {
|
|
15
35
|
private config;
|
|
16
|
-
constructor(config: OAuthConfig);
|
|
17
|
-
authorize(): Promise<
|
|
36
|
+
constructor(config: OAuthConfig<T>);
|
|
37
|
+
authorize(): Promise<T>;
|
|
18
38
|
private checkForCallback;
|
|
19
39
|
private buildOAuthUrl;
|
|
20
40
|
private generateState;
|
|
21
41
|
}
|
|
22
42
|
|
|
23
|
-
declare function createOAuthClient(config: OAuthConfig): OAuthClient
|
|
43
|
+
declare function createOAuthClient<T = OAuthResult>(config: OAuthConfig<T>): OAuthClient<T>;
|
|
24
44
|
|
|
25
|
-
export { type OAuthClient, type OAuthConfig, type OAuthResult, WebOAuthClient, createOAuthClient };
|
|
45
|
+
export { type OAuthCallbackParams, type OAuthClient, type OAuthConfig, type OAuthResult, WebOAuthClient, createOAuthClient };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,25 +1,45 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Raw callback parameters from OAuth redirect
|
|
3
|
+
* Contains all query parameters returned by the OAuth provider
|
|
4
|
+
*/
|
|
5
|
+
type OAuthCallbackParams = Record<string, string | undefined>;
|
|
6
|
+
/**
|
|
7
|
+
* Default OAuth result with standard code and state
|
|
8
|
+
*/
|
|
6
9
|
interface OAuthResult {
|
|
7
10
|
code: string;
|
|
8
11
|
state?: string;
|
|
9
12
|
}
|
|
10
|
-
|
|
11
|
-
|
|
13
|
+
/**
|
|
14
|
+
* OAuth configuration options
|
|
15
|
+
*/
|
|
16
|
+
interface OAuthConfig<T = OAuthResult> {
|
|
17
|
+
oauthUrl: string;
|
|
18
|
+
redirectUrl: string;
|
|
19
|
+
additionalParameters?: Record<string, string>;
|
|
20
|
+
/**
|
|
21
|
+
* Optional transformer to convert raw callback params to desired type
|
|
22
|
+
* If not provided, returns all callback params as-is (typed as T)
|
|
23
|
+
*/
|
|
24
|
+
transformCallback?: (params: OAuthCallbackParams) => T;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* OAuth client interface with generic result type
|
|
28
|
+
* @template T - The type returned from authorize(), defaults to OAuthResult
|
|
29
|
+
*/
|
|
30
|
+
interface OAuthClient<T = OAuthResult> {
|
|
31
|
+
authorize(): Promise<T>;
|
|
12
32
|
}
|
|
13
33
|
|
|
14
|
-
declare class WebOAuthClient implements OAuthClient {
|
|
34
|
+
declare class WebOAuthClient<T = OAuthResult> implements OAuthClient<T> {
|
|
15
35
|
private config;
|
|
16
|
-
constructor(config: OAuthConfig);
|
|
17
|
-
authorize(): Promise<
|
|
36
|
+
constructor(config: OAuthConfig<T>);
|
|
37
|
+
authorize(): Promise<T>;
|
|
18
38
|
private checkForCallback;
|
|
19
39
|
private buildOAuthUrl;
|
|
20
40
|
private generateState;
|
|
21
41
|
}
|
|
22
42
|
|
|
23
|
-
declare function createOAuthClient(config: OAuthConfig): OAuthClient
|
|
43
|
+
declare function createOAuthClient<T = OAuthResult>(config: OAuthConfig<T>): OAuthClient<T>;
|
|
24
44
|
|
|
25
|
-
export { type OAuthClient, type OAuthConfig, type OAuthResult, WebOAuthClient, createOAuthClient };
|
|
45
|
+
export { type OAuthCallbackParams, type OAuthClient, type OAuthConfig, type OAuthResult, WebOAuthClient, createOAuthClient };
|
package/dist/index.js
CHANGED
|
@@ -32,19 +32,16 @@ var WebOAuthClient = class {
|
|
|
32
32
|
}
|
|
33
33
|
async authorize() {
|
|
34
34
|
const state = this.generateState();
|
|
35
|
-
const
|
|
36
|
-
if (
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
throw new Error(`OAuth error: ${error}`);
|
|
35
|
+
const callbackParams = this.checkForCallback();
|
|
36
|
+
if (callbackParams) {
|
|
37
|
+
if (callbackParams.error) {
|
|
38
|
+
throw new Error(`OAuth error: ${callbackParams.error}`);
|
|
40
39
|
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
return
|
|
44
|
-
code,
|
|
45
|
-
state: returnedState || void 0
|
|
46
|
-
};
|
|
40
|
+
window.history.replaceState({}, document.title, window.location.pathname);
|
|
41
|
+
if (this.config.transformCallback) {
|
|
42
|
+
return this.config.transformCallback(callbackParams);
|
|
47
43
|
}
|
|
44
|
+
return callbackParams;
|
|
48
45
|
}
|
|
49
46
|
const oauthUrl = this.buildOAuthUrl(state);
|
|
50
47
|
window.location.href = oauthUrl;
|
|
@@ -52,17 +49,14 @@ var WebOAuthClient = class {
|
|
|
52
49
|
}
|
|
53
50
|
checkForCallback() {
|
|
54
51
|
const urlParams = new URLSearchParams(window.location.search);
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
error: error || void 0,
|
|
62
|
-
returnedState: state || void 0
|
|
63
|
-
};
|
|
52
|
+
const params = {};
|
|
53
|
+
urlParams.forEach((value, key) => {
|
|
54
|
+
params[key] = value;
|
|
55
|
+
});
|
|
56
|
+
if (Object.keys(params).length === 0) {
|
|
57
|
+
return null;
|
|
64
58
|
}
|
|
65
|
-
return
|
|
59
|
+
return params;
|
|
66
60
|
}
|
|
67
61
|
buildOAuthUrl(state) {
|
|
68
62
|
const url = new URL(this.config.oauthUrl);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/oauth-client.web.ts","../src/index.web.ts"],"sourcesContent":["export * from './index.web'","import type { OAuthClient, OAuthConfig, OAuthResult } from './types'\n\nexport class WebOAuthClient implements OAuthClient {\n private config: OAuthConfig
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/oauth-client.web.ts","../src/index.web.ts"],"sourcesContent":["export * from './index.web'","import type { OAuthClient, OAuthConfig, OAuthResult, OAuthCallbackParams } from './types'\n\nexport class WebOAuthClient<T = OAuthResult> implements OAuthClient<T> {\n private config: OAuthConfig<T>\n\n constructor(config: OAuthConfig<T>) {\n this.config = config\n }\n\n async authorize(): Promise<T> {\n const state = this.generateState()\n\n // Check if we're already in a callback\n const callbackParams = this.checkForCallback()\n\n if (callbackParams) {\n if (callbackParams.error) {\n throw new Error(`OAuth error: ${callbackParams.error}`)\n }\n\n // Clean up URL\n window.history.replaceState({}, document.title, window.location.pathname)\n\n // Transform callback params if transformer provided, otherwise return as-is\n if (this.config.transformCallback) {\n return this.config.transformCallback(callbackParams)\n }\n\n // Default behavior: return all callback params as T\n return callbackParams as T\n }\n\n // Build OAuth URL and redirect\n const oauthUrl = this.buildOAuthUrl(state)\n window.location.href = oauthUrl\n\n // This won't be reached due to redirect\n throw new Error('Authorization flow initiated')\n }\n\n private checkForCallback(): OAuthCallbackParams | null {\n const urlParams = new URLSearchParams(window.location.search)\n const params: OAuthCallbackParams = {}\n\n // Collect all query parameters\n urlParams.forEach((value, key) => {\n params[key] = value\n })\n\n // Return null if no parameters found\n if (Object.keys(params).length === 0) {\n return null\n }\n\n return params\n }\n\n private buildOAuthUrl(state: string): string {\n const url = new URL(this.config.oauthUrl)\n \n url.searchParams.set('redirect_uri', this.config.redirectUrl)\n url.searchParams.set('state', state)\n\n // Add additional parameters\n if (this.config.additionalParameters) {\n Object.entries(this.config.additionalParameters).forEach(([key, value]) => {\n url.searchParams.set(key, value)\n })\n }\n\n return url.toString()\n }\n\n private generateState(): string {\n // Generate random state for CSRF protection\n let result = ''\n const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~'\n for (let i = 0; i < 32; i++) {\n result += chars.charAt(Math.floor(Math.random() * chars.length))\n }\n return result\n }\n}","export * from './types'\n\nimport type { OAuthConfig, OAuthClient, OAuthResult } from './types'\nimport { WebOAuthClient } from './oauth-client.web'\n\nexport function createOAuthClient<T = OAuthResult>(config: OAuthConfig<T>): OAuthClient<T> {\n return new WebOAuthClient<T>(config)\n}\n\nexport { WebOAuthClient }"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACEO,IAAM,iBAAN,MAAgE;AAAA,EAGrE,YAAY,QAAwB;AAClC,SAAK,SAAS;AAAA,EAChB;AAAA,EAEA,MAAM,YAAwB;AAC5B,UAAM,QAAQ,KAAK,cAAc;AAGjC,UAAM,iBAAiB,KAAK,iBAAiB;AAE7C,QAAI,gBAAgB;AAClB,UAAI,eAAe,OAAO;AACxB,cAAM,IAAI,MAAM,gBAAgB,eAAe,KAAK,EAAE;AAAA,MACxD;AAGA,aAAO,QAAQ,aAAa,CAAC,GAAG,SAAS,OAAO,OAAO,SAAS,QAAQ;AAGxE,UAAI,KAAK,OAAO,mBAAmB;AACjC,eAAO,KAAK,OAAO,kBAAkB,cAAc;AAAA,MACrD;AAGA,aAAO;AAAA,IACT;AAGA,UAAM,WAAW,KAAK,cAAc,KAAK;AACzC,WAAO,SAAS,OAAO;AAGvB,UAAM,IAAI,MAAM,8BAA8B;AAAA,EAChD;AAAA,EAEQ,mBAA+C;AACrD,UAAM,YAAY,IAAI,gBAAgB,OAAO,SAAS,MAAM;AAC5D,UAAM,SAA8B,CAAC;AAGrC,cAAU,QAAQ,CAAC,OAAO,QAAQ;AAChC,aAAO,GAAG,IAAI;AAAA,IAChB,CAAC;AAGD,QAAI,OAAO,KAAK,MAAM,EAAE,WAAW,GAAG;AACpC,aAAO;AAAA,IACT;AAEA,WAAO;AAAA,EACT;AAAA,EAEQ,cAAc,OAAuB;AAC3C,UAAM,MAAM,IAAI,IAAI,KAAK,OAAO,QAAQ;AAExC,QAAI,aAAa,IAAI,gBAAgB,KAAK,OAAO,WAAW;AAC5D,QAAI,aAAa,IAAI,SAAS,KAAK;AAGnC,QAAI,KAAK,OAAO,sBAAsB;AACpC,aAAO,QAAQ,KAAK,OAAO,oBAAoB,EAAE,QAAQ,CAAC,CAAC,KAAK,KAAK,MAAM;AACzE,YAAI,aAAa,IAAI,KAAK,KAAK;AAAA,MACjC,CAAC;AAAA,IACH;AAEA,WAAO,IAAI,SAAS;AAAA,EACtB;AAAA,EAEQ,gBAAwB;AAE9B,QAAI,SAAS;AACb,UAAM,QAAQ;AACd,aAAS,IAAI,GAAG,IAAI,IAAI,KAAK;AAC3B,gBAAU,MAAM,OAAO,KAAK,MAAM,KAAK,OAAO,IAAI,MAAM,MAAM,CAAC;AAAA,IACjE;AACA,WAAO;AAAA,EACT;AACF;;;AC7EO,SAAS,kBAAmC,QAAwC;AACzF,SAAO,IAAI,eAAkB,MAAM;AACrC;","names":[]}
|
package/dist/index.mjs
CHANGED
|
@@ -5,19 +5,16 @@ var WebOAuthClient = class {
|
|
|
5
5
|
}
|
|
6
6
|
async authorize() {
|
|
7
7
|
const state = this.generateState();
|
|
8
|
-
const
|
|
9
|
-
if (
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
throw new Error(`OAuth error: ${error}`);
|
|
8
|
+
const callbackParams = this.checkForCallback();
|
|
9
|
+
if (callbackParams) {
|
|
10
|
+
if (callbackParams.error) {
|
|
11
|
+
throw new Error(`OAuth error: ${callbackParams.error}`);
|
|
13
12
|
}
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
return
|
|
17
|
-
code,
|
|
18
|
-
state: returnedState || void 0
|
|
19
|
-
};
|
|
13
|
+
window.history.replaceState({}, document.title, window.location.pathname);
|
|
14
|
+
if (this.config.transformCallback) {
|
|
15
|
+
return this.config.transformCallback(callbackParams);
|
|
20
16
|
}
|
|
17
|
+
return callbackParams;
|
|
21
18
|
}
|
|
22
19
|
const oauthUrl = this.buildOAuthUrl(state);
|
|
23
20
|
window.location.href = oauthUrl;
|
|
@@ -25,17 +22,14 @@ var WebOAuthClient = class {
|
|
|
25
22
|
}
|
|
26
23
|
checkForCallback() {
|
|
27
24
|
const urlParams = new URLSearchParams(window.location.search);
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
error: error || void 0,
|
|
35
|
-
returnedState: state || void 0
|
|
36
|
-
};
|
|
25
|
+
const params = {};
|
|
26
|
+
urlParams.forEach((value, key) => {
|
|
27
|
+
params[key] = value;
|
|
28
|
+
});
|
|
29
|
+
if (Object.keys(params).length === 0) {
|
|
30
|
+
return null;
|
|
37
31
|
}
|
|
38
|
-
return
|
|
32
|
+
return params;
|
|
39
33
|
}
|
|
40
34
|
buildOAuthUrl(state) {
|
|
41
35
|
const url = new URL(this.config.oauthUrl);
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/oauth-client.web.ts","../src/index.web.ts"],"sourcesContent":["import type { OAuthClient, OAuthConfig, OAuthResult } from './types'\n\nexport class WebOAuthClient implements OAuthClient {\n private config: OAuthConfig
|
|
1
|
+
{"version":3,"sources":["../src/oauth-client.web.ts","../src/index.web.ts"],"sourcesContent":["import type { OAuthClient, OAuthConfig, OAuthResult, OAuthCallbackParams } from './types'\n\nexport class WebOAuthClient<T = OAuthResult> implements OAuthClient<T> {\n private config: OAuthConfig<T>\n\n constructor(config: OAuthConfig<T>) {\n this.config = config\n }\n\n async authorize(): Promise<T> {\n const state = this.generateState()\n\n // Check if we're already in a callback\n const callbackParams = this.checkForCallback()\n\n if (callbackParams) {\n if (callbackParams.error) {\n throw new Error(`OAuth error: ${callbackParams.error}`)\n }\n\n // Clean up URL\n window.history.replaceState({}, document.title, window.location.pathname)\n\n // Transform callback params if transformer provided, otherwise return as-is\n if (this.config.transformCallback) {\n return this.config.transformCallback(callbackParams)\n }\n\n // Default behavior: return all callback params as T\n return callbackParams as T\n }\n\n // Build OAuth URL and redirect\n const oauthUrl = this.buildOAuthUrl(state)\n window.location.href = oauthUrl\n\n // This won't be reached due to redirect\n throw new Error('Authorization flow initiated')\n }\n\n private checkForCallback(): OAuthCallbackParams | null {\n const urlParams = new URLSearchParams(window.location.search)\n const params: OAuthCallbackParams = {}\n\n // Collect all query parameters\n urlParams.forEach((value, key) => {\n params[key] = value\n })\n\n // Return null if no parameters found\n if (Object.keys(params).length === 0) {\n return null\n }\n\n return params\n }\n\n private buildOAuthUrl(state: string): string {\n const url = new URL(this.config.oauthUrl)\n \n url.searchParams.set('redirect_uri', this.config.redirectUrl)\n url.searchParams.set('state', state)\n\n // Add additional parameters\n if (this.config.additionalParameters) {\n Object.entries(this.config.additionalParameters).forEach(([key, value]) => {\n url.searchParams.set(key, value)\n })\n }\n\n return url.toString()\n }\n\n private generateState(): string {\n // Generate random state for CSRF protection\n let result = ''\n const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~'\n for (let i = 0; i < 32; i++) {\n result += chars.charAt(Math.floor(Math.random() * chars.length))\n }\n return result\n }\n}","export * from './types'\n\nimport type { OAuthConfig, OAuthClient, OAuthResult } from './types'\nimport { WebOAuthClient } from './oauth-client.web'\n\nexport function createOAuthClient<T = OAuthResult>(config: OAuthConfig<T>): OAuthClient<T> {\n return new WebOAuthClient<T>(config)\n}\n\nexport { WebOAuthClient }"],"mappings":";AAEO,IAAM,iBAAN,MAAgE;AAAA,EAGrE,YAAY,QAAwB;AAClC,SAAK,SAAS;AAAA,EAChB;AAAA,EAEA,MAAM,YAAwB;AAC5B,UAAM,QAAQ,KAAK,cAAc;AAGjC,UAAM,iBAAiB,KAAK,iBAAiB;AAE7C,QAAI,gBAAgB;AAClB,UAAI,eAAe,OAAO;AACxB,cAAM,IAAI,MAAM,gBAAgB,eAAe,KAAK,EAAE;AAAA,MACxD;AAGA,aAAO,QAAQ,aAAa,CAAC,GAAG,SAAS,OAAO,OAAO,SAAS,QAAQ;AAGxE,UAAI,KAAK,OAAO,mBAAmB;AACjC,eAAO,KAAK,OAAO,kBAAkB,cAAc;AAAA,MACrD;AAGA,aAAO;AAAA,IACT;AAGA,UAAM,WAAW,KAAK,cAAc,KAAK;AACzC,WAAO,SAAS,OAAO;AAGvB,UAAM,IAAI,MAAM,8BAA8B;AAAA,EAChD;AAAA,EAEQ,mBAA+C;AACrD,UAAM,YAAY,IAAI,gBAAgB,OAAO,SAAS,MAAM;AAC5D,UAAM,SAA8B,CAAC;AAGrC,cAAU,QAAQ,CAAC,OAAO,QAAQ;AAChC,aAAO,GAAG,IAAI;AAAA,IAChB,CAAC;AAGD,QAAI,OAAO,KAAK,MAAM,EAAE,WAAW,GAAG;AACpC,aAAO;AAAA,IACT;AAEA,WAAO;AAAA,EACT;AAAA,EAEQ,cAAc,OAAuB;AAC3C,UAAM,MAAM,IAAI,IAAI,KAAK,OAAO,QAAQ;AAExC,QAAI,aAAa,IAAI,gBAAgB,KAAK,OAAO,WAAW;AAC5D,QAAI,aAAa,IAAI,SAAS,KAAK;AAGnC,QAAI,KAAK,OAAO,sBAAsB;AACpC,aAAO,QAAQ,KAAK,OAAO,oBAAoB,EAAE,QAAQ,CAAC,CAAC,KAAK,KAAK,MAAM;AACzE,YAAI,aAAa,IAAI,KAAK,KAAK;AAAA,MACjC,CAAC;AAAA,IACH;AAEA,WAAO,IAAI,SAAS;AAAA,EACtB;AAAA,EAEQ,gBAAwB;AAE9B,QAAI,SAAS;AACb,UAAM,QAAQ;AACd,aAAS,IAAI,GAAG,IAAI,IAAI,KAAK;AAC3B,gBAAU,MAAM,OAAO,KAAK,MAAM,KAAK,OAAO,IAAI,MAAM,MAAM,CAAC;AAAA,IACjE;AACA,WAAO;AAAA,EACT;AACF;;;AC7EO,SAAS,kBAAmC,QAAwC;AACzF,SAAO,IAAI,eAAkB,MAAM;AACrC;","names":[]}
|
package/package.json
CHANGED
package/src/index.native.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
export * from './types'
|
|
2
2
|
|
|
3
|
-
import type { OAuthConfig, OAuthClient } from './types'
|
|
3
|
+
import type { OAuthConfig, OAuthClient, OAuthResult } from './types'
|
|
4
4
|
import { NativeOAuthClient } from './oauth-client.native'
|
|
5
5
|
|
|
6
|
-
export function createOAuthClient(config: OAuthConfig): OAuthClient {
|
|
7
|
-
return new NativeOAuthClient(config)
|
|
6
|
+
export function createOAuthClient<T = OAuthResult>(config: OAuthConfig<T>): OAuthClient<T> {
|
|
7
|
+
return new NativeOAuthClient<T>(config)
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
export { NativeOAuthClient }
|
package/src/index.web.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
export * from './types'
|
|
2
2
|
|
|
3
|
-
import type { OAuthConfig, OAuthClient } from './types'
|
|
3
|
+
import type { OAuthConfig, OAuthClient, OAuthResult } from './types'
|
|
4
4
|
import { WebOAuthClient } from './oauth-client.web'
|
|
5
5
|
|
|
6
|
-
export function createOAuthClient(config: OAuthConfig): OAuthClient {
|
|
7
|
-
return new WebOAuthClient(config)
|
|
6
|
+
export function createOAuthClient<T = OAuthResult>(config: OAuthConfig<T>): OAuthClient<T> {
|
|
7
|
+
return new WebOAuthClient<T>(config)
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
export { WebOAuthClient }
|
|
@@ -1,38 +1,37 @@
|
|
|
1
|
-
import type { OAuthClient, OAuthConfig, OAuthResult } from './types'
|
|
1
|
+
import type { OAuthClient, OAuthConfig, OAuthResult, OAuthCallbackParams } from './types'
|
|
2
2
|
import { Linking } from 'react-native'
|
|
3
3
|
|
|
4
|
-
export class NativeOAuthClient implements OAuthClient {
|
|
5
|
-
private config: OAuthConfig
|
|
4
|
+
export class NativeOAuthClient<T = OAuthResult> implements OAuthClient<T> {
|
|
5
|
+
private config: OAuthConfig<T>
|
|
6
6
|
|
|
7
|
-
constructor(config: OAuthConfig) {
|
|
7
|
+
constructor(config: OAuthConfig<T>) {
|
|
8
8
|
this.config = config
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
async authorize(): Promise<
|
|
11
|
+
async authorize(): Promise<T> {
|
|
12
12
|
const state = this.generateState()
|
|
13
13
|
const oauthUrl = this.buildOAuthUrl(state)
|
|
14
|
-
|
|
14
|
+
|
|
15
15
|
// Open OAuth URL in system browser
|
|
16
16
|
await Linking.openURL(oauthUrl)
|
|
17
|
-
|
|
17
|
+
|
|
18
18
|
// Wait for deep link callback
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
if (
|
|
22
|
-
throw new Error(`OAuth error: ${
|
|
19
|
+
const callbackParams = await this.waitForDeepLinkCallback()
|
|
20
|
+
|
|
21
|
+
if (callbackParams.error) {
|
|
22
|
+
throw new Error(`OAuth error: ${callbackParams.error}`)
|
|
23
23
|
}
|
|
24
|
-
|
|
25
|
-
if
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
state: callbackData.state
|
|
29
|
-
}
|
|
24
|
+
|
|
25
|
+
// Transform callback params if transformer provided, otherwise return as-is
|
|
26
|
+
if (this.config.transformCallback) {
|
|
27
|
+
return this.config.transformCallback(callbackParams)
|
|
30
28
|
}
|
|
31
|
-
|
|
32
|
-
|
|
29
|
+
|
|
30
|
+
// Default behavior: return all callback params as T
|
|
31
|
+
return callbackParams as T
|
|
33
32
|
}
|
|
34
33
|
|
|
35
|
-
private async waitForDeepLinkCallback(): Promise<
|
|
34
|
+
private async waitForDeepLinkCallback(): Promise<OAuthCallbackParams> {
|
|
36
35
|
return new Promise((resolve, reject) => {
|
|
37
36
|
let subscription: any
|
|
38
37
|
let timeoutId: NodeJS.Timeout | null = null
|
|
@@ -82,47 +81,39 @@ export class NativeOAuthClient implements OAuthClient {
|
|
|
82
81
|
})
|
|
83
82
|
}
|
|
84
83
|
|
|
85
|
-
private parseDeepLink(url: string):
|
|
84
|
+
private parseDeepLink(url: string): OAuthCallbackParams | null {
|
|
86
85
|
try {
|
|
87
86
|
// Handle custom scheme URLs (e.g., com.myapp://oauth/callback?code=123)
|
|
88
87
|
const parsedUrl = new URL(url)
|
|
89
|
-
|
|
88
|
+
|
|
90
89
|
// Check if this is our OAuth callback
|
|
91
90
|
const expectedScheme = new URL(this.config.redirectUrl).protocol.slice(0, -1)
|
|
92
91
|
if (parsedUrl.protocol.slice(0, -1) !== expectedScheme) {
|
|
93
92
|
return null
|
|
94
93
|
}
|
|
95
94
|
|
|
96
|
-
//
|
|
97
|
-
const
|
|
98
|
-
|
|
99
|
-
|
|
95
|
+
// Collect all query parameters
|
|
96
|
+
const params: OAuthCallbackParams = {}
|
|
97
|
+
|
|
98
|
+
// Get all parameters from query string
|
|
99
|
+
parsedUrl.searchParams.forEach((value, key) => {
|
|
100
|
+
params[key] = value
|
|
101
|
+
})
|
|
100
102
|
|
|
101
103
|
// Also check the hash fragment for parameters (some OAuth providers use this)
|
|
102
|
-
if (
|
|
104
|
+
if (Object.keys(params).length === 0 && parsedUrl.hash) {
|
|
103
105
|
const hashParams = new URLSearchParams(parsedUrl.hash.substring(1))
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
if (hashCode || hashError) {
|
|
109
|
-
return {
|
|
110
|
-
code: hashCode || undefined,
|
|
111
|
-
error: hashError || undefined,
|
|
112
|
-
state: hashState || undefined
|
|
113
|
-
}
|
|
114
|
-
}
|
|
106
|
+
hashParams.forEach((value, key) => {
|
|
107
|
+
params[key] = value
|
|
108
|
+
})
|
|
115
109
|
}
|
|
116
110
|
|
|
117
|
-
if
|
|
111
|
+
// Return null if no parameters found
|
|
112
|
+
if (Object.keys(params).length === 0) {
|
|
118
113
|
return null
|
|
119
114
|
}
|
|
120
115
|
|
|
121
|
-
return
|
|
122
|
-
code: code || undefined,
|
|
123
|
-
error: error || undefined,
|
|
124
|
-
state: state || undefined
|
|
125
|
-
}
|
|
116
|
+
return params
|
|
126
117
|
} catch (error) {
|
|
127
118
|
console.warn('Failed to parse deep link URL:', url, error)
|
|
128
119
|
return null
|
package/src/oauth-client.web.ts
CHANGED
|
@@ -1,59 +1,58 @@
|
|
|
1
|
-
import type { OAuthClient, OAuthConfig, OAuthResult } from './types'
|
|
1
|
+
import type { OAuthClient, OAuthConfig, OAuthResult, OAuthCallbackParams } from './types'
|
|
2
2
|
|
|
3
|
-
export class WebOAuthClient implements OAuthClient {
|
|
4
|
-
private config: OAuthConfig
|
|
3
|
+
export class WebOAuthClient<T = OAuthResult> implements OAuthClient<T> {
|
|
4
|
+
private config: OAuthConfig<T>
|
|
5
5
|
|
|
6
|
-
constructor(config: OAuthConfig) {
|
|
6
|
+
constructor(config: OAuthConfig<T>) {
|
|
7
7
|
this.config = config
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
-
async authorize(): Promise<
|
|
10
|
+
async authorize(): Promise<T> {
|
|
11
11
|
const state = this.generateState()
|
|
12
12
|
|
|
13
13
|
// Check if we're already in a callback
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
if (
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
if (error) {
|
|
20
|
-
throw new Error(`OAuth error: ${error}`)
|
|
14
|
+
const callbackParams = this.checkForCallback()
|
|
15
|
+
|
|
16
|
+
if (callbackParams) {
|
|
17
|
+
if (callbackParams.error) {
|
|
18
|
+
throw new Error(`OAuth error: ${callbackParams.error}`)
|
|
21
19
|
}
|
|
22
20
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
state: returnedState || undefined
|
|
30
|
-
}
|
|
21
|
+
// Clean up URL
|
|
22
|
+
window.history.replaceState({}, document.title, window.location.pathname)
|
|
23
|
+
|
|
24
|
+
// Transform callback params if transformer provided, otherwise return as-is
|
|
25
|
+
if (this.config.transformCallback) {
|
|
26
|
+
return this.config.transformCallback(callbackParams)
|
|
31
27
|
}
|
|
28
|
+
|
|
29
|
+
// Default behavior: return all callback params as T
|
|
30
|
+
return callbackParams as T
|
|
32
31
|
}
|
|
33
32
|
|
|
34
33
|
// Build OAuth URL and redirect
|
|
35
34
|
const oauthUrl = this.buildOAuthUrl(state)
|
|
36
35
|
window.location.href = oauthUrl
|
|
37
|
-
|
|
36
|
+
|
|
38
37
|
// This won't be reached due to redirect
|
|
39
38
|
throw new Error('Authorization flow initiated')
|
|
40
39
|
}
|
|
41
40
|
|
|
42
|
-
private checkForCallback():
|
|
41
|
+
private checkForCallback(): OAuthCallbackParams | null {
|
|
43
42
|
const urlParams = new URLSearchParams(window.location.search)
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
43
|
+
const params: OAuthCallbackParams = {}
|
|
44
|
+
|
|
45
|
+
// Collect all query parameters
|
|
46
|
+
urlParams.forEach((value, key) => {
|
|
47
|
+
params[key] = value
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
// Return null if no parameters found
|
|
51
|
+
if (Object.keys(params).length === 0) {
|
|
52
|
+
return null
|
|
54
53
|
}
|
|
55
|
-
|
|
56
|
-
return
|
|
54
|
+
|
|
55
|
+
return params
|
|
57
56
|
}
|
|
58
57
|
|
|
59
58
|
private buildOAuthUrl(state: string): string {
|
package/src/types.ts
CHANGED
|
@@ -1,19 +1,41 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Raw callback parameters from OAuth redirect
|
|
3
|
+
* Contains all query parameters returned by the OAuth provider
|
|
4
|
+
*/
|
|
5
|
+
export type OAuthCallbackParams = Record<string, string | undefined>
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Default OAuth result with standard code and state
|
|
9
|
+
*/
|
|
10
|
+
export interface OAuthResult {
|
|
11
|
+
code: string
|
|
12
|
+
state?: string
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* OAuth configuration options
|
|
17
|
+
*/
|
|
18
|
+
export interface OAuthConfig<T = OAuthResult> {
|
|
2
19
|
// OAuth endpoint URL (e.g., "https://api.yourapp.com/auth/google")
|
|
3
20
|
oauthUrl: string
|
|
4
|
-
|
|
21
|
+
|
|
5
22
|
// Redirect URL for the client app (e.g., "com.yourapp://oauth/callback")
|
|
6
23
|
redirectUrl: string
|
|
7
|
-
|
|
24
|
+
|
|
8
25
|
// Optional additional parameters to send to OAuth endpoint
|
|
9
26
|
additionalParameters?: Record<string, string>
|
|
10
|
-
}
|
|
11
27
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
28
|
+
/**
|
|
29
|
+
* Optional transformer to convert raw callback params to desired type
|
|
30
|
+
* If not provided, returns all callback params as-is (typed as T)
|
|
31
|
+
*/
|
|
32
|
+
transformCallback?: (params: OAuthCallbackParams) => T
|
|
15
33
|
}
|
|
16
34
|
|
|
17
|
-
|
|
18
|
-
|
|
35
|
+
/**
|
|
36
|
+
* OAuth client interface with generic result type
|
|
37
|
+
* @template T - The type returned from authorize(), defaults to OAuthResult
|
|
38
|
+
*/
|
|
39
|
+
export interface OAuthClient<T = OAuthResult> {
|
|
40
|
+
authorize(): Promise<T>
|
|
19
41
|
}
|