@openai-oauth/web 2.0.0-beta.2 → 2.0.0-beta.3
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/README.md +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +56 -4
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -26,9 +26,9 @@ await fetch("/api/chat", {
|
|
|
26
26
|
|
|
27
27
|
### Hosted Sign-in
|
|
28
28
|
|
|
29
|
-
Hosted browser sign-in uses the open-source
|
|
29
|
+
Hosted browser sign-in uses the open-source Sign in with ChatGPT extension for [Chrome](https://chromewebstore.google.com/detail/sign-in-with-chatgpt/odbgboachaefbbbdiffcefhpkekhfcna) or [Firefox](https://addons.mozilla.org/firefox/addon/sign-in-with-chatgpt/) to complete OpenAI's local OAuth callback. The extension shows the destination app for confirmation and then returns the callback directly to it.
|
|
30
30
|
|
|
31
|
-
`startLogin()` uses this extension flow by default. When installation is needed, it returns the
|
|
31
|
+
`startLogin()` uses this extension flow by default. When installation is needed, it returns the correct Chrome Web Store or Firefox Add-ons URL for your interface to display:
|
|
32
32
|
|
|
33
33
|
```ts
|
|
34
34
|
import { startLogin } from "@openai-oauth/web";
|
|
@@ -43,7 +43,7 @@ if (result.status === "needs-extension") {
|
|
|
43
43
|
|
|
44
44
|
After installation, call `startLogin()` again when the user returns to your app or presses Sign in again. It will start OAuth once the extension is available.
|
|
45
45
|
|
|
46
|
-
The extension
|
|
46
|
+
The extension redirects only `http://localhost:1455/auth/callback`. After the user confirms the destination, call `completeLogin()` on the returned app URL to exchange the code and save the browser session.
|
|
47
47
|
|
|
48
48
|
`startLogin()` returns `{ status: "started" }` when OAuth begins or `{ status: "needs-extension", installUrl }` when your interface should show installation UI. Provide an explicit `redirectUri` only when your environment handles its own registered callback without the extension.
|
|
49
49
|
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAIN,KAAK,aAAa,EAClB,KAAK,yBAAyB,EAC9B,KAAK,kBAAkB,EAIvB,KAAK,YAAY,EACjB,MAAM,oBAAoB,CAAA;AAE3B,YAAY,EAAE,kBAAkB,EAAE,YAAY,EAAE,CAAA;AAEhD,MAAM,MAAM,0BAA0B,GAAG;IACxC,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,SAAS,CAAC,EAAE,MAAM,CAAA;CAClB,CAAA;AAED,MAAM,MAAM,uBAAuB,GAAG;IACrC,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,KAAK,CAAC,EAAE,aAAa,CAAA;IACrB,GAAG,CAAC,EAAE,MAAM,IAAI,CAAA;CAChB,CAAA;AAED,MAAM,MAAM,mBAAmB,GAAG,uBAAuB,CAAA;AAEzD,MAAM,MAAM,iBAAiB,GAAG;IAC/B,IAAI,EAAE,MAAM,CAAA;IACZ,YAAY,EAAE,MAAM,CAAA;IACpB,WAAW,EAAE,MAAM,CAAA;IACnB,MAAM,CAAC,EAAE,WAAW,CAAA;CACpB,CAAA;AAED,MAAM,MAAM,qBAAqB,GAAG,uBAAuB,CAAA;AAE3D,MAAM,MAAM,mBAAmB,GAAG;IACjC,YAAY,EAAE,MAAM,CAAA;IACpB,MAAM,CAAC,EAAE,WAAW,CAAA;CACpB,CAAA;AAED,MAAM,MAAM,qBAAqB,GAAG;IACnC,YAAY,CAAC,EAAE,YAAY,CAAA;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,KAAK,CAAC,EAAE,aAAa,CAAA;IACrB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,GAAG,CAAC,EAAE,MAAM,IAAI,CAAA;CAChB,CAAA;AAED,MAAM,MAAM,wBAAwB,GAAG,qBAAqB,GAAG;IAC9D,OAAO,CAAC,EAAE,WAAW,CAAA;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAA;CAClB,CAAA;AAED,MAAM,MAAM,iBAAiB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;AAEtD,MAAM,MAAM,iBAAiB,GAAG,IAAI,CACnC,yBAAyB,EACzB,aAAa,CACb,GAAG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,UAAU,GAAG,OAAO,CAAA;CAC/B,CAAA;AAED,MAAM,MAAM,oBAAoB,GAAG;IAClC,YAAY,CAAC,EAAE,YAAY,CAAA;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,KAAK,CAAC,EAAE,aAAa,CAAA;IACrB,GAAG,CAAC,EAAE,MAAM,IAAI,CAAA;IAChB,GAAG,CAAC,EAAE,MAAM,CAAA;CACZ,CAAA;AAED,MAAM,MAAM,aAAa,GAAG;IAC3B,YAAY,CAAC,EAAE,YAAY,CAAA;CAC3B,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -10,7 +10,10 @@ const browserExtensionStatePrefix = "oo2_";
|
|
|
10
10
|
const browserExtensionRedirectUri = "http://localhost:1455/auth/callback";
|
|
11
11
|
const browserExtensionId = "odbgboachaefbbbdiffcefhpkekhfcna";
|
|
12
12
|
const browserExtensionInstalledPath = "src/installed.json";
|
|
13
|
-
const
|
|
13
|
+
const chromeExtensionInstallUrl = "https://chromewebstore.google.com/detail/sign-in-with-chatgpt/odbgboachaefbbbdiffcefhpkekhfcna";
|
|
14
|
+
const firefoxExtensionInstallUrl = "https://addons.mozilla.org/firefox/addon/sign-in-with-chatgpt/";
|
|
15
|
+
const firefoxExtensionDetectionUrl = "http://localhost:1455/openai-oauth/installed";
|
|
16
|
+
const browserExtensionMarkerType = "openai-oauth:browser-extension-installed";
|
|
14
17
|
const browserExtensionDetectionTimeoutMs = 750;
|
|
15
18
|
const refreshExpiryMarginMs = 5 * 60 * 1000;
|
|
16
19
|
const refreshIntervalMs = 55 * 60 * 1000;
|
|
@@ -28,7 +31,9 @@ const assertBrowserWindow = () => {
|
|
|
28
31
|
}
|
|
29
32
|
return window;
|
|
30
33
|
};
|
|
31
|
-
const
|
|
34
|
+
const isFirefox = () => typeof navigator !== "undefined" &&
|
|
35
|
+
navigator.userAgent.toLowerCase().includes("firefox/");
|
|
36
|
+
const isChromeExtensionInstalled = async () => {
|
|
32
37
|
const fetchImpl = globalThis.fetch;
|
|
33
38
|
if (!fetchImpl) {
|
|
34
39
|
return false;
|
|
@@ -57,6 +62,52 @@ const isBrowserExtensionInstalled = async () => {
|
|
|
57
62
|
}
|
|
58
63
|
}
|
|
59
64
|
};
|
|
65
|
+
const isFirefoxExtensionInstalled = (browserWindow) => new Promise((resolve) => {
|
|
66
|
+
const document = browserWindow.document;
|
|
67
|
+
const parent = document?.body ?? document?.documentElement;
|
|
68
|
+
if (!document?.createElement || !parent) {
|
|
69
|
+
resolve(false);
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
const iframe = document.createElement("iframe");
|
|
73
|
+
iframe.hidden = true;
|
|
74
|
+
iframe.setAttribute("aria-hidden", "true");
|
|
75
|
+
iframe.src = firefoxExtensionDetectionUrl;
|
|
76
|
+
let settled = false;
|
|
77
|
+
const finish = (installed) => {
|
|
78
|
+
if (settled) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
settled = true;
|
|
82
|
+
globalThis.clearTimeout(timeout);
|
|
83
|
+
browserWindow.removeEventListener("message", onMessage);
|
|
84
|
+
iframe.remove();
|
|
85
|
+
resolve(installed);
|
|
86
|
+
};
|
|
87
|
+
const onMessage = (event) => {
|
|
88
|
+
const data = event.data;
|
|
89
|
+
if (event.source === iframe.contentWindow &&
|
|
90
|
+
event.origin.startsWith("moz-extension://") &&
|
|
91
|
+
data?.type === browserExtensionMarkerType &&
|
|
92
|
+
data.name === "sign-in-with-chatgpt" &&
|
|
93
|
+
data.protocol === "openai-oauth-browser-extension" &&
|
|
94
|
+
data.protocolVersion === 1) {
|
|
95
|
+
finish(true);
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
const timeout = globalThis.setTimeout(() => finish(false), browserExtensionDetectionTimeoutMs);
|
|
99
|
+
browserWindow.addEventListener("message", onMessage);
|
|
100
|
+
parent.appendChild(iframe);
|
|
101
|
+
});
|
|
102
|
+
const getBrowserExtension = (browserWindow) => isFirefox()
|
|
103
|
+
? {
|
|
104
|
+
installUrl: firefoxExtensionInstallUrl,
|
|
105
|
+
isInstalled: () => isFirefoxExtensionInstalled(browserWindow),
|
|
106
|
+
}
|
|
107
|
+
: {
|
|
108
|
+
installUrl: chromeExtensionInstallUrl,
|
|
109
|
+
isInstalled: isChromeExtensionInstalled,
|
|
110
|
+
};
|
|
60
111
|
const requestToPromise = (request) => new Promise((resolve, reject) => {
|
|
61
112
|
request.onsuccess = () => resolve(request.result);
|
|
62
113
|
request.onerror = () => reject(request.error ?? new Error("IndexedDB request failed."));
|
|
@@ -370,10 +421,11 @@ const createBrowserExtensionState = (callbackUrl, appState) => {
|
|
|
370
421
|
export const startLogin = async (options = {}) => {
|
|
371
422
|
const browserWindow = assertBrowserWindow();
|
|
372
423
|
const usesBrowserExtension = options.redirectUri === undefined;
|
|
373
|
-
|
|
424
|
+
const browserExtension = getBrowserExtension(browserWindow);
|
|
425
|
+
if (usesBrowserExtension && !(await browserExtension.isInstalled())) {
|
|
374
426
|
return {
|
|
375
427
|
status: "needs-extension",
|
|
376
|
-
installUrl:
|
|
428
|
+
installUrl: browserExtension.installUrl,
|
|
377
429
|
};
|
|
378
430
|
}
|
|
379
431
|
const returnTo = options.returnTo ?? getCurrentRelativeUrl();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openai-oauth/web",
|
|
3
|
-
"version": "2.0.0-beta.
|
|
3
|
+
"version": "2.0.0-beta.3",
|
|
4
4
|
"description": "Browser credential storage and web utilities for openai-oauth.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"openai",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"access": "public"
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"@openai-oauth/core": "2.0.0-beta.
|
|
44
|
+
"@openai-oauth/core": "2.0.0-beta.3"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
47
|
"@types/node": "20.17.24",
|