@openai-oauth/react 2.0.0-beta.0 → 2.0.0-beta.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/README.md CHANGED
@@ -26,7 +26,7 @@ export default function Page() {
26
26
 
27
27
  The prebuilt button includes a small "Powered by OpenAI OAuth" link by default. Pass `hideAttribution` to render only the button with no attribution link or reserved space.
28
28
 
29
- No app route is required for login. The hook creates the authorization URL, stores PKCE/state in `sessionStorage`, exchanges the callback code directly, and stores the resulting session in the browser session store.
29
+ Hosted web apps need the open-source [Sign in with ChatGPT Chrome extension](https://chromewebstore.google.com/detail/sign-in-with-chatgpt/odbgboachaefbbbdiffcefhpkekhfcna) to complete the OAuth handoff securely. `SignInWithChatGPT` detects whether it is installed, shows the install screen when needed, and automatically continues once installation is detected. Developers do not need to configure the extension separately.
30
30
 
31
31
  Browser model calls must go through your own app route because ChatGPT does not allow direct browser CORS requests. Send the signed-in session to that route with `openaiAuthHeaders()`:
32
32
 
@@ -48,6 +48,8 @@ async function ask() {
48
48
  }
49
49
  ```
50
50
 
51
+ `openaiAuthHeaders()` returns a plain object, so it can be passed directly to `fetch`, AI SDK hooks, and other code that spreads header objects.
52
+
51
53
  Read the request-bound credentials on your server:
52
54
 
53
55
  ```ts
@@ -79,7 +81,7 @@ Useful props:
79
81
  />
80
82
  ```
81
83
 
82
- For custom UI, use the hook:
84
+ For custom UI, use the hook. Custom interfaces are responsible for presenting the extension installation link when needed.
83
85
 
84
86
  ```tsx
85
87
  import { useSignInWithChatGPT } from "@openai-oauth/react";
@@ -91,6 +93,18 @@ function CustomLogin() {
91
93
  return <button onClick={() => void login.logout()}>Disconnect</button>;
92
94
  }
93
95
 
96
+ if (login.status === "needs-extension") {
97
+ return (
98
+ <div>
99
+ <a href={login.installUrl} rel="noreferrer" target="_blank">
100
+ Install Sign in with ChatGPT
101
+ </a>
102
+ <button onClick={() => void login.login()}>Try again</button>
103
+ <button onClick={login.reset}>Cancel</button>
104
+ </div>
105
+ );
106
+ }
107
+
94
108
  return (
95
109
  <button onClick={() => void login.login()}>Sign in with ChatGPT</button>
96
110
  );
@@ -112,7 +126,7 @@ type UseSignInWithChatGPTReturn = SignInWithChatGPTState & {
112
126
  State statuses:
113
127
 
114
128
  ```ts
115
- "checking" | "signed-out" | "starting" | "redirecting" | "signed-in" | "error"
129
+ "checking" | "signed-out" | "starting" | "needs-extension" | "redirecting" | "signed-in" | "error"
116
130
  ```
117
131
 
118
132
  The default browser session store persists encrypted sessions in IndexedDB. Apps can provide their own store:
@@ -8,5 +8,5 @@ export type SignInWithChatGPTProps = Omit<ButtonHTMLAttributes<HTMLButtonElement
8
8
  hideWhenSignedIn?: boolean;
9
9
  showLogo?: boolean;
10
10
  };
11
- export declare const SignInWithChatGPT: ({ callbackPath, clientId, codeVerifier, sessionStore, extraParams, fetch, idTokenAddOrganizations, issuer, onSuccess, onError, onStateChange, openMode, redirectUri, scope, simplifiedFlow, state, loadingLabel, redirectingLabel, signedInLabel, hideAttribution, hideWhenSignedIn, showLogo, children, disabled, onClick, onMouseEnter, onMouseLeave, style, type, ...props }: SignInWithChatGPTProps) => import("react").JSX.Element | null;
11
+ export declare const SignInWithChatGPT: ({ callbackPath, clientId, codeVerifier, sessionStore, extraParams, fetch, idTokenAddOrganizations, issuer, now, onSuccess, onError, onStateChange, openMode, redirectUri, scope, simplifiedFlow, state, tokenUrl, loadingLabel, redirectingLabel, signedInLabel, hideAttribution, hideWhenSignedIn, showLogo, children, disabled, onClick, onMouseEnter, onMouseLeave, style, type, ...props }: SignInWithChatGPTProps) => import("react").JSX.Element | null;
12
12
  //# sourceMappingURL=SignInWithChatGPT.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"SignInWithChatGPT.d.ts","sourceRoot":"","sources":["../src/SignInWithChatGPT.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,oBAAoB,EAIpB,MAAM,OAAO,CAAA;AAEd,OAAO,EACN,KAAK,2BAA2B,EAEhC,MAAM,2BAA2B,CAAA;AAElC,MAAM,MAAM,sBAAsB,GAAG,IAAI,CACxC,oBAAoB,CAAC,iBAAiB,CAAC,EACvC,SAAS,CACT,GACA,2BAA2B,GAAG;IAC7B,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,QAAQ,CAAC,EAAE,OAAO,CAAA;CAClB,CAAA;AAkEF,eAAO,MAAM,iBAAiB,GAAI,iXA+B/B,sBAAsB,uCA6FxB,CAAA"}
1
+ {"version":3,"file":"SignInWithChatGPT.d.ts","sourceRoot":"","sources":["../src/SignInWithChatGPT.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,oBAAoB,EAIpB,MAAM,OAAO,CAAA;AAGd,OAAO,EACN,KAAK,2BAA2B,EAEhC,MAAM,2BAA2B,CAAA;AAElC,MAAM,MAAM,sBAAsB,GAAG,IAAI,CACxC,oBAAoB,CAAC,iBAAiB,CAAC,EACvC,SAAS,CACT,GACA,2BAA2B,GAAG;IAC7B,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,QAAQ,CAAC,EAAE,OAAO,CAAA;CAClB,CAAA;AAkEF,eAAO,MAAM,iBAAiB,GAAI,gYAiC/B,sBAAsB,uCA8GxB,CAAA"}
@@ -1,5 +1,6 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { useState } from "react";
3
+ import { SignInWithChatGPTExtensionScreen } from "./SignInWithChatGPTExtensionScreen.js";
3
4
  import { useSignInWithChatGPT, } from "./useSignInWithChatGPT.js";
4
5
  const containerStyle = {
5
6
  alignItems: "center",
@@ -43,7 +44,7 @@ const attributionStyle = {
43
44
  textUnderlineOffset: 2,
44
45
  };
45
46
  const OpenAILogo = () => (_jsxs("svg", { "aria-hidden": "true", fill: "none", focusable: "false", style: logoStyle, viewBox: "0 0 5086 5021", xmlns: "http://www.w3.org/2000/svg", children: [_jsx("title", { children: "OpenAI" }), _jsx("path", { d: "M1947.45 1832.08V1357.04C1947.45 1317.03 1962.45 1287.01 1997.43 1267.05L2952.46 717.024C3082.47 642.035 3237.47 607.018 3397.45 607.018C3997.47 607.018 4377.48 1072.05 4377.48 1567.07C4377.48 1602.06 4377.48 1642.06 4372.46 1682.07L3382.45 1102.04C3322.46 1067.03 3262.46 1067.03 3202.45 1102.04L1947.45 1832.08ZM4177.46 3682.19V2547.08C4177.46 2477.08 4147.44 2427.07 4087.45 2392.08L2832.45 1662.05L3242.46 1427.01C3277.44 1407.02 3307.47 1407.02 3342.45 1427.01L4297.47 1977.03C4572.51 2137.05 4757.46 2477.08 4757.46 2807.06C4757.46 3187.06 4532.51 3537.1 4177.46 3682.12V3682.19ZM1652.43 2682.13L1242.42 2442.13C1207.44 2422.14 1192.44 2392.11 1192.44 2352.14V1252.09C1192.44 717.057 1602.45 312.018 2157.48 312.018C2367.47 312.018 2562.43 382.019 2727.5 507.022L1742.48 1077.07C1682.49 1112.05 1652.49 1162.07 1652.49 1232.1V2682.16L1652.43 2682.13ZM2534.98 3192.15L1947.38 2862.13V2162.13L2534.91 1832.11L3122.41 2162.13V2862.13L2534.98 3192.15ZM2912.45 4712.24C2702.43 4712.24 2507.46 4642.21 2342.43 4517.24L3327.42 3947.16C3387.41 3912.17 3417.43 3862.19 3417.43 3792.16V2342.07L3832.46 2582.06C3867.45 2602.05 3882.44 2632.08 3882.44 2672.08V3772.14C3882.44 4307.14 3467.41 4712.24 2912.45 4712.24ZM1727.41 3597.19L772.388 3047.16C497.352 2887.14 312.365 2547.15 312.365 2217.13C312.365 1832.11 542.409 1487.1 897.386 1342.07V2482.13C897.386 2552.17 927.38 2602.15 987.369 2637.13L2237.42 3362.15L1827.41 3597.19C1792.42 3617.17 1762.4 3617.17 1727.41 3597.19ZM1672.45 4417.24C1107.44 4417.24 692.414 3992.18 692.414 3467.16C692.414 3427.16 697.434 3387.15 702.422 3347.15L1687.41 3917.19C1747.42 3952.19 1807.42 3952.19 1867.41 3917.19L3122.41 3192.18V3667.22C3122.41 3707.22 3107.42 3737.22 3072.43 3757.21L2117.41 4307.23C1987.39 4382.22 1832.39 4417.24 1672.38 4417.24H1672.45ZM2912.45 5012.23C3517.46 5012.23 4022.44 4582.22 4137.49 4012.17C4697.48 3867.15 5057.51 3342.13 5057.51 2807.13C5057.51 2457.09 4907.5 2117.1 4637.49 1872.05C4662.49 1767.06 4677.52 1662.05 4677.52 1557.1C4677.52 842.06 4097.49 306.997 3427.48 306.997C3292.5 306.997 3162.48 326.951 3032.46 371.977C2807.44 151.966 2497.45 11.9648 2157.44 11.9648C1552.44 11.9648 1047.46 441.978 932.434 1012.02C372.419 1157.05 12.4219 1682.03 12.4219 2217.06C12.4219 2567.13 162.394 2907.13 432.408 3152.14C407.402 3257.13 392.405 3362.15 392.405 3467.13C392.405 4182.13 972.404 4717.2 1642.45 4717.2C1777.43 4717.2 1907.41 4697.24 2037.43 4652.22C2262.39 4872.23 2572.41 5012.23 2912.45 5012.23Z", fill: "currentColor" })] }));
46
- export const SignInWithChatGPT = ({ callbackPath, clientId, codeVerifier, sessionStore, extraParams, fetch, idTokenAddOrganizations, issuer, onSuccess, onError, onStateChange, openMode, redirectUri, scope, simplifiedFlow, state, loadingLabel = "Connecting...", redirectingLabel = "Signing in...", signedInLabel = "Disconnect ChatGPT", hideAttribution = false, hideWhenSignedIn = false, showLogo = true, children = "Sign in with ChatGPT", disabled, onClick, onMouseEnter, onMouseLeave, style, type = "button", ...props }) => {
47
+ export const SignInWithChatGPT = ({ callbackPath, clientId, codeVerifier, sessionStore, extraParams, fetch, idTokenAddOrganizations, issuer, now, onSuccess, onError, onStateChange, openMode, redirectUri, scope, simplifiedFlow, state, tokenUrl, loadingLabel = "Connecting...", redirectingLabel = "Signing in...", signedInLabel = "Disconnect ChatGPT", hideAttribution = false, hideWhenSignedIn = false, showLogo = true, children = "Sign in with ChatGPT", disabled, onClick, onMouseEnter, onMouseLeave, style, type = "button", ...props }) => {
47
48
  const [isHovered, setIsHovered] = useState(false);
48
49
  const login = useSignInWithChatGPT({
49
50
  callbackPath,
@@ -54,6 +55,7 @@ export const SignInWithChatGPT = ({ callbackPath, clientId, codeVerifier, sessio
54
55
  fetch,
55
56
  idTokenAddOrganizations,
56
57
  issuer,
58
+ now,
57
59
  onSuccess,
58
60
  onError,
59
61
  onStateChange,
@@ -62,9 +64,11 @@ export const SignInWithChatGPT = ({ callbackPath, clientId, codeVerifier, sessio
62
64
  scope,
63
65
  simplifiedFlow,
64
66
  state,
67
+ tokenUrl,
65
68
  });
66
69
  const isBusy = login.status === "starting" || login.status === "redirecting";
67
70
  const isSignedIn = login.status === "signed-in";
71
+ const needsExtension = login.status === "needs-extension";
68
72
  const handleClick = (event) => {
69
73
  onClick?.(event);
70
74
  if (event.defaultPrevented) {
@@ -87,6 +91,7 @@ export const SignInWithChatGPT = ({ callbackPath, clientId, codeVerifier, sessio
87
91
  if (hideWhenSignedIn && isSignedIn) {
88
92
  return null;
89
93
  }
94
+ const extensionScreen = needsExtension ? (_jsx(SignInWithChatGPTExtensionScreen, { installUrl: login.installUrl, onCancel: login.reset, onContinue: login.login })) : null;
90
95
  const button = (_jsxs("button", { ...props, type: type, disabled: disabled || isBusy, onClick: handleClick, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, style: {
91
96
  ...buttonStyle,
92
97
  background: isHovered && !disabled && !isBusy ? "#f9f9f9" : "#ffffff",
@@ -99,7 +104,7 @@ export const SignInWithChatGPT = ({ callbackPath, clientId, codeVerifier, sessio
99
104
  ? signedInLabel
100
105
  : children })] }));
101
106
  if (hideAttribution) {
102
- return button;
107
+ return (_jsxs(_Fragment, { children: [button, extensionScreen] }));
103
108
  }
104
- return (_jsxs("span", { style: containerStyle, children: [button, _jsx("a", { href: "https://github.com/EvanZhouDev/openai-oauth", rel: "noreferrer", style: attributionStyle, target: "_blank", children: "Powered by OpenAI OAuth" })] }));
109
+ return (_jsxs("span", { style: containerStyle, children: [button, _jsx("a", { href: "https://github.com/EvanZhouDev/openai-oauth", rel: "noreferrer", style: attributionStyle, target: "_blank", children: "Powered by OpenAI OAuth" }), extensionScreen] }));
105
110
  };
@@ -0,0 +1,7 @@
1
+ export type SignInWithChatGPTExtensionScreenProps = {
2
+ installUrl: string;
3
+ onCancel?: () => void;
4
+ onContinue: () => void | Promise<void>;
5
+ };
6
+ export declare const SignInWithChatGPTExtensionScreen: ({ installUrl, onCancel, onContinue, }: SignInWithChatGPTExtensionScreenProps) => import("react").JSX.Element;
7
+ //# sourceMappingURL=SignInWithChatGPTExtensionScreen.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SignInWithChatGPTExtensionScreen.d.ts","sourceRoot":"","sources":["../src/SignInWithChatGPTExtensionScreen.tsx"],"names":[],"mappings":"AAGA,MAAM,MAAM,qCAAqC,GAAG;IACnD,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;IACrB,UAAU,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CACtC,CAAA;AAoND,eAAO,MAAM,gCAAgC,GAAI,uCAI9C,qCAAqC,gCAuLvC,CAAA"}
@@ -0,0 +1,244 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useEffect, useRef, useState } from "react";
3
+ const defaultGithubUrl = "https://github.com/evanzhoudev/openai-oauth";
4
+ const defaultLegalUrl = "https://github.com/evanzhoudev/openai-oauth#legal";
5
+ const defaultPollIntervalMs = 500;
6
+ const popupName = "openai-oauth-extension-install";
7
+ const popupWidth = 1350;
8
+ const popupHeight = 760;
9
+ const logoSrc = "data:image/svg+xml,%3Csvg%20width%3D%221412%22%20height%3D%221412%22%20viewBox%3D%220%200%201412%201412%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%0A%3Cstyle%3E%0A.mark%20%7B%20fill%3A%20%23111111%3B%20%7D%0A%40media%20(prefers-color-scheme%3A%20dark)%20%7B%0A%20%20.mark%20%7B%20fill%3A%20%23ffffff%3B%20%7D%0A%7D%0A%3C%2Fstyle%3E%0A%3Cg%20clip-path%3D%22url(%23clip0_36_7)%22%3E%0A%3Cpath%20class%3D%22mark%22%20d%3D%22M597.462%200.857699C673.717%20-4.5771%20755.535%2016.0618%20820.557%2055.7878C839.621%2067.4347%20853.532%2077.8804%20870.903%2091.7881C915.947%2083.6597%20962.083%2083.5966%201007.15%2091.601C1108.64%20109.677%201198.75%20167.436%201257.54%20252.101C1315.95%20336.355%201338.56%20440.326%201320.41%20541.218C1348.4%20575.095%201369.47%20609.408%201385.5%20650.519C1422.8%20746.143%201420.65%20852.641%201379.53%20946.681C1345.7%201023.88%201287.62%201087.95%201214.08%201129.17C1193.85%201140.47%201177.72%201147.33%201156.35%201155.65C1150.8%201167.38%201146.43%201180.08%201140.53%201192.52C1124.33%201226.23%201103.33%201257.42%201078.21%201285.12C1009.53%201360.77%20913.675%201406.14%20811.622%201411.3C797.103%201412.74%20770.195%201411.71%20755.535%201410.39C669.671%201402.64%20607.216%201373.41%20541.228%201320.14C498.371%201327.97%20454.491%201328.42%20411.479%201321.49C309.519%201305.16%20218.308%201248.8%20158.127%201164.91C95.5192%201077.93%2074.597%20975.652%2091.7694%20870.624C63.5815%20837.852%2041.1539%20800.536%2025.4414%20760.272C-11.0983%20663.999%20-8.18036%20557.204%2033.5617%20463.069C77.8418%20363.472%20155.004%20295.015%20255.809%20256.181C260.004%20248.164%20265.705%20231.947%20270.502%20221.837C286.044%20188.764%20306.234%20158.081%20330.46%20130.717C398.638%2053.6473%20494.725%206.91416%20597.462%200.857699ZM803.624%201297.49C879.882%201292.64%20946.234%201261.95%20997.071%201204.28C1015.09%201183.82%201029.9%201160.75%201041.02%201135.85C1047.58%201121.23%201051.8%201106.22%201056.86%201091.08C1067.19%201060.2%201088.78%201058.15%201115.61%201048.88C1125.47%201045.52%201135.09%201041.52%201144.43%201036.9C1243.91%20988.43%201304.38%20884.819%201297.64%20774.394C1294%20716.163%201271.8%20660.631%201234.27%20615.946C1223.26%20602.711%201208.28%20591.435%201203.34%20574.896C1197.16%20554.244%201207.83%20529.807%201210.67%20506.759C1221.87%20416.705%201187.69%20326.959%201119.41%20267.154C1064.95%20219.454%20993.758%20195.357%20921.517%20200.173C909.062%20200.932%20896.689%20202.63%20884.487%20205.252C858.307%20210.809%20839.711%20217.803%20816.524%20196.759C802.123%20183.693%20793.783%20175.007%20777.726%20163.451C738.141%20135.075%20691.432%20118.286%20642.835%20114.967C634.456%20114.329%20619.975%20113.369%20611.816%20114.357C536.156%20118.188%20468.827%20147.965%20417.756%20204.614C399.016%20225.371%20383.578%20248.884%20371.981%20274.328C368.409%20282.286%20365.23%20290.414%20362.455%20298.682C357.28%20314.179%20354.556%20330.003%20342.859%20342.026C330.473%20354.758%20314.132%20357.158%20297.998%20362.604C288.467%20365.803%20279.144%20369.592%20270.084%20373.948C170.322%20421.514%20108.992%20524.42%20114.64%20634.77C117.764%20693.592%20139.719%20749.855%20177.266%20795.249C188.357%20808.68%20203.749%20820.374%20208.712%20836.975C214.929%20857.779%20204.623%20882.481%20201.669%20905.586C190.625%20994.243%20223.634%201082.71%20290.065%201142.47C341.827%201188.92%20413.829%201216.16%20483.523%201212.31C496.702%201211.71%20509.821%201210.17%20522.783%201207.71C549.917%201202.44%20573.428%201193.61%20595.85%201215.61C654.397%201273.04%20720.807%201298.82%20803.624%201297.49Z%22%2F%3E%0A%3Cpath%20class%3D%22mark%22%20fill-rule%3D%22evenodd%22%20clip-rule%3D%22evenodd%22%20d%3D%22M528.104%20673.1C645.003%20673.1%20739.769%20767.837%20739.769%20884.701C739.769%201001.56%20645.003%201096.3%20528.104%201096.3C411.204%201096.3%20316.439%201001.56%20316.439%20884.701C316.439%20767.837%20411.204%20673.1%20528.104%20673.1ZM526.618%20785.954C472.886%20785.954%20429.327%20829.499%20429.327%20883.216C429.327%20936.932%20472.886%20980.478%20526.618%20980.478C580.351%20980.478%20623.91%20936.932%20623.91%20883.216C623.91%20829.499%20580.351%20785.954%20526.618%20785.954Z%22%2F%3E%0A%3Cpath%20class%3D%22mark%22%20d%3D%22M974.454%20335.733L1055.33%20416.583L688.769%20783.031L607.895%20702.182L974.454%20335.733Z%22%2F%3E%0A%3Cpath%20class%3D%22mark%22%20d%3D%22M820.585%20766.758L704.525%20767.283L821.11%20650.733L820.585%20766.758Z%22%2F%3E%0A%3Cpath%20class%3D%22mark%22%20d%3D%22M937.694%20649.684L821.11%20650.733L938.744%20533.135L937.694%20649.684Z%22%2F%3E%0A%3Cpath%20class%3D%22mark%22%20d%3D%22M1054.8%20532.611L938.744%20533.135L1055.33%20416.586L1054.8%20532.611Z%22%2F%3E%0A%3Cpath%20class%3D%22mark%22%20d%3D%22M1054.8%20336.259L1055.33%20416.583L974.454%20335.733L1054.8%20336.259Z%22%2F%3E%0A%3C%2Fg%3E%0A%3Cdefs%3E%0A%3CclipPath%20id%3D%22clip0_36_7%22%3E%0A%3Crect%20width%3D%221412%22%20height%3D%221412%22%20fill%3D%22white%22%2F%3E%0A%3C%2FclipPath%3E%0A%3C%2Fdefs%3E%0A%3C%2Fsvg%3E%0A";
10
+ const wordmarkSrc = "data:image/svg+xml,%3Csvg%20width%3D%222769%22%20height%3D%22391%22%20viewBox%3D%220%200%202769%20391%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%0A%3Cpath%20d%3D%22M2495.6%20239.383L2495.6%204.36719H2442.96L2442.96%20251.081C2442.96%20264.073%202446.69%20279.793%202455.73%20289.364C2464.76%20298.935%202471.68%20305.315%202488.69%20305.315H2549.84V263.31H2514.21C2507.02%20263.31%202501.82%20258.862%202499.33%20254.803C2496.83%20250.743%202495.6%20246.21%202495.6%20239.383Z%22%20fill%3D%22black%22%2F%3E%0A%3Crect%20x%3D%222543.46%22%20y%3D%2290.5039%22%20width%3D%2247.854%22%20height%3D%22146.752%22%20transform%3D%22rotate(90%202543.46%2090.5039)%22%20fill%3D%22black%22%2F%3E%0A%3Cpath%20d%3D%22M1734.79%200C1649.66%200%201580%2069.6496%201580%20154.777C1580%20239.904%201649.66%20309.554%201734.79%20309.554C1819.93%20309.554%201889.59%20240.334%201889.59%20154.777C1889.59%2069.2197%201820.36%200%201734.79%200ZM1734.79%20254.092C1681.91%20254.092%201639.34%20210.669%201639.34%20154.777C1639.34%2098.8852%201681.91%2055.4617%201734.79%2055.4617C1787.68%2055.4617%201830.25%2098.8852%201830.25%20154.777C1830.25%20210.669%201787.68%20254.092%201734.79%20254.092Z%22%20fill%3D%22black%22%2F%3E%0A%3Cpath%20d%3D%22M1984.56%208.62109L1862.87%20309.576H1922.64L1948.44%20243.796H2086.89L2112.69%20309.576H2173.32L2052.49%208.62109H1984.56ZM1967.79%20193.923L2017.67%2067.9522L2067.11%20193.923H1967.79Z%22%20fill%3D%22black%22%2F%3E%0A%3Cpath%20d%3D%22M2687.02%2086.0449C2662.08%2086.0449%202635.86%2097.2232%202623.82%20115.71V4.36719H2567.92V305.312H2623.82V189.659C2623.82%20156.124%202641.88%20134.198%202671.11%20134.198C2698.2%20134.198%202712.82%20154.835%202712.82%20183.64V305.312H2768.72V174.612C2768.72%20121.3%202736.04%2086.0449%202687.02%2086.0449Z%22%20fill%3D%22black%22%2F%3E%0A%3Cpath%20d%3D%22M2255.09%20309.773C2280.02%20309.773%202306.25%20298.595%202318.29%20280.108L2318.29%20305.474L2374.19%20305.474L2374.19%2090.5062L2318.29%2090.5062L2318.29%20206.159C2318.29%20239.694%202300.23%20261.621%202271%20261.621C2243.91%20261.621%202229.29%20240.984%202229.29%20212.178L2229.29%2090.5062L2173.39%2090.5062L2173.39%20221.207C2173.39%20274.519%202206.07%20309.773%202255.09%20309.773Z%22%20fill%3D%22black%22%2F%3E%0A%3Cpath%20d%3D%22M154.577%200C69.5595%200%200%2069.6066%200%20154.681C0%20239.756%2069.5595%20309.363%20154.577%20309.363C239.594%20309.363%20309.153%20240.186%20309.153%20154.681C309.153%2069.1769%20240.023%200%20154.577%200ZM154.577%20253.935C101.763%20253.935%2059.2544%20210.538%2059.2544%20154.681C59.2544%2098.8242%20101.763%2055.4275%20154.577%2055.4275C207.39%2055.4275%20249.899%2098.8242%20249.899%20154.681C249.899%20210.538%20207.39%20253.935%20154.577%20253.935ZM465.447%2085.9341C437.533%2085.9341%20410.487%2097.1055%20396.312%20116.011V90.2308H340.493V391H396.312V282.293C410.482%20299.91%20436.674%20309.363%20465.442%20309.363C525.555%20309.363%20572.787%20262.099%20572.787%20197.648C572.787%20133.198%20525.561%2085.9341%20465.447%2085.9341ZM455.996%20260.81C424.222%20260.81%20395.883%20235.889%20395.883%20197.648C395.883%20159.408%20424.222%20134.487%20455.996%20134.487C487.77%20134.487%20516.104%20159.408%20516.104%20197.648C516.104%20235.889%20487.77%20260.81%20455.996%20260.81ZM704.187%2085.9341C643.216%2085.9341%20595.125%20133.627%20595.125%20197.648C595.125%20261.669%20637.204%20309.363%20705.905%20309.363C762.154%20309.363%20798.222%20275.419%20809.385%20237.178H754.854C747.984%20253.076%20728.662%20264.247%20705.476%20264.247C676.707%20264.247%20654.809%20244.053%20649.656%20215.265H811.962V193.352C811.962%20134.916%20771.171%2085.9341%20704.187%2085.9341ZM650.086%20175.735C656.097%20148.666%20678.425%20131.049%20705.476%20131.049C734.244%20131.049%20756.142%20149.955%20758.719%20175.735H650.086ZM960.522%2085.9341C935.618%2085.9341%20909.426%2097.1055%20897.403%20115.581V90.2308H841.584V305.066H897.403V189.485C897.403%20155.97%20915.437%20134.057%20944.635%20134.057C971.686%20134.057%20986.285%20154.681%20986.285%20183.469V305.066H1042.1V174.446C1042.1%20121.167%201009.47%2085.9341%20960.522%2085.9341ZM1185.07%204.30681L1063.55%20305.076H1123.24L1149%20239.336H1287.26L1313.02%20305.076H1373.56L1252.91%204.30681H1185.07ZM1168.32%20189.495L1218.13%2063.6013L1267.51%20189.495H1168.32ZM1453%204.30681H1396.32V305.076H1453V4.30681Z%22%20fill%3D%22black%22%2F%3E%0A%3C%2Fsvg%3E%0A";
11
+ const systemFont = 'ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif';
12
+ const screenStyle = {
13
+ alignItems: "center",
14
+ background: "#ffffff",
15
+ color: "#111111",
16
+ display: "flex",
17
+ fontFamily: systemFont,
18
+ inset: 0,
19
+ justifyContent: "center",
20
+ padding: "36px 24px",
21
+ position: "fixed",
22
+ zIndex: 2147483647,
23
+ };
24
+ const stackStyle = {
25
+ alignItems: "center",
26
+ display: "flex",
27
+ flexDirection: "column",
28
+ textAlign: "center",
29
+ width: "min(100%, 430px)",
30
+ };
31
+ const brandStyle = {
32
+ alignItems: "center",
33
+ display: "inline-flex",
34
+ gap: 7,
35
+ marginBottom: 28,
36
+ };
37
+ const logoStyle = {
38
+ display: "block",
39
+ height: 16,
40
+ transform: "translateY(-1px)",
41
+ width: 16,
42
+ };
43
+ const wordmarkStyle = {
44
+ display: "block",
45
+ height: 15,
46
+ width: "auto",
47
+ };
48
+ const titleStyle = {
49
+ fontSize: "clamp(25px, 3.1vw, 31px)",
50
+ fontWeight: 540,
51
+ letterSpacing: 0,
52
+ lineHeight: 1.1,
53
+ margin: 0,
54
+ whiteSpace: "nowrap",
55
+ };
56
+ const leadStyle = {
57
+ color: "#111111",
58
+ fontSize: 18,
59
+ lineHeight: 1.45,
60
+ margin: "18px auto 0",
61
+ maxWidth: 330,
62
+ };
63
+ const listStyle = {
64
+ alignItems: "flex-start",
65
+ display: "grid",
66
+ gap: 14,
67
+ listStyle: "none",
68
+ margin: "34px 0 0",
69
+ padding: 0,
70
+ textAlign: "left",
71
+ width: "fit-content",
72
+ };
73
+ const itemStyle = {
74
+ alignItems: "center",
75
+ color: "#6f6f6f",
76
+ display: "flex",
77
+ fontSize: 18,
78
+ gap: 14,
79
+ lineHeight: 1.4,
80
+ };
81
+ const checkStyle = {
82
+ color: "#6f6f6f",
83
+ flex: "0 0 auto",
84
+ height: 17,
85
+ width: 17,
86
+ };
87
+ const primaryButtonStyle = {
88
+ alignItems: "center",
89
+ appearance: "none",
90
+ background: "#111111",
91
+ border: 0,
92
+ borderRadius: 9999,
93
+ boxSizing: "border-box",
94
+ color: "#ffffff",
95
+ cursor: "pointer",
96
+ display: "inline-flex",
97
+ fontFamily: systemFont,
98
+ fontSize: 15,
99
+ fontWeight: 500,
100
+ justifyContent: "center",
101
+ lineHeight: 1.2,
102
+ minHeight: 50,
103
+ padding: "13px 24px",
104
+ width: "100%",
105
+ };
106
+ const actionsStyle = {
107
+ alignItems: "stretch",
108
+ display: "flex",
109
+ flexDirection: "column",
110
+ gap: 12,
111
+ marginTop: 38,
112
+ width: "min(100%, 322px)",
113
+ };
114
+ const secondaryButtonStyle = {
115
+ ...primaryButtonStyle,
116
+ background: "#ffffff",
117
+ border: "1px solid #d9d9d9",
118
+ color: "#111111",
119
+ };
120
+ const statusStyle = {
121
+ color: "#8f8f8f",
122
+ fontSize: 13,
123
+ lineHeight: 1.3,
124
+ margin: "2px 0 0",
125
+ minHeight: "1.3em",
126
+ };
127
+ const footerStyle = {
128
+ alignItems: "center",
129
+ bottom: 34,
130
+ color: "#6f6f6f",
131
+ display: "flex",
132
+ flexDirection: "column",
133
+ fontSize: 12,
134
+ gap: 7,
135
+ left: 24,
136
+ lineHeight: 1.25,
137
+ position: "fixed",
138
+ right: 24,
139
+ textAlign: "center",
140
+ };
141
+ const footerLinksStyle = {
142
+ alignItems: "center",
143
+ display: "flex",
144
+ gap: 8,
145
+ justifyContent: "center",
146
+ };
147
+ const linkStyle = {
148
+ color: "inherit",
149
+ textDecoration: "none",
150
+ };
151
+ const sourceLinkStyle = {
152
+ ...linkStyle,
153
+ textDecoration: "underline",
154
+ textDecorationColor: "#d9d9d9",
155
+ textUnderlineOffset: 3,
156
+ };
157
+ const sourceArrowStyle = {
158
+ display: "inline-block",
159
+ fontSize: 12,
160
+ marginLeft: 3,
161
+ transform: "translateY(-1px)",
162
+ };
163
+ const CheckIcon = () => (_jsx("svg", { "aria-hidden": "true", style: checkStyle, viewBox: "0 0 20 20", children: _jsx("path", { d: "M8.1 13.7 4.4 10l-1.3 1.3 5 5L17 7.4 15.7 6z", fill: "currentColor" }) }));
164
+ const getCenteredPopupFeatures = () => {
165
+ const width = Math.min(popupWidth, window.screen.availWidth);
166
+ const height = Math.min(popupHeight, window.screen.availHeight);
167
+ const left = Math.round(window.screenX + (window.outerWidth - width) / 2);
168
+ const top = Math.round(window.screenY + (window.outerHeight - height) / 2);
169
+ return [
170
+ "popup=yes",
171
+ `width=${width}`,
172
+ `height=${height}`,
173
+ `left=${left}`,
174
+ `top=${top}`,
175
+ ].join(",");
176
+ };
177
+ export const SignInWithChatGPTExtensionScreen = ({ installUrl, onCancel, onContinue, }) => {
178
+ const [status, setStatus] = useState("");
179
+ const hasOpenedInstallWindowRef = useRef(false);
180
+ const onContinueRef = useRef(onContinue);
181
+ onContinueRef.current = onContinue;
182
+ useEffect(() => {
183
+ let active = true;
184
+ let checking = false;
185
+ let timeoutId;
186
+ const tryContinue = async () => {
187
+ if (checking) {
188
+ return;
189
+ }
190
+ if (timeoutId !== undefined) {
191
+ window.clearTimeout(timeoutId);
192
+ timeoutId = undefined;
193
+ }
194
+ checking = true;
195
+ await onContinueRef.current();
196
+ checking = false;
197
+ if (!active) {
198
+ return;
199
+ }
200
+ timeoutId = window.setTimeout(tryContinue, defaultPollIntervalMs);
201
+ };
202
+ const checkOnReturn = () => {
203
+ if (document.visibilityState === "visible") {
204
+ void tryContinue();
205
+ }
206
+ };
207
+ window.addEventListener("focus", checkOnReturn);
208
+ document.addEventListener("visibilitychange", checkOnReturn);
209
+ void tryContinue();
210
+ return () => {
211
+ active = false;
212
+ window.removeEventListener("focus", checkOnReturn);
213
+ document.removeEventListener("visibilitychange", checkOnReturn);
214
+ if (timeoutId !== undefined) {
215
+ window.clearTimeout(timeoutId);
216
+ }
217
+ };
218
+ }, []);
219
+ const handlePrimaryClick = () => {
220
+ if (hasOpenedInstallWindowRef.current) {
221
+ setStatus("Chrome Web Store is already open.");
222
+ return;
223
+ }
224
+ setStatus("Waiting for extension to be installed...");
225
+ const features = getCenteredPopupFeatures();
226
+ const opened = window.open(installUrl, popupName, features);
227
+ if (opened) {
228
+ hasOpenedInstallWindowRef.current = true;
229
+ opened.focus();
230
+ return;
231
+ }
232
+ const tab = window.open(installUrl, "_blank");
233
+ if (tab) {
234
+ hasOpenedInstallWindowRef.current = true;
235
+ tab.focus();
236
+ return;
237
+ }
238
+ setStatus("Popup blocked. Please allow popups or open the Chrome Web Store.");
239
+ };
240
+ const handleCancelClick = () => {
241
+ onCancel?.();
242
+ };
243
+ return (_jsxs("div", { "aria-labelledby": "openai-oauth-extension-title", "aria-modal": "true", role: "dialog", style: screenStyle, children: [_jsxs("section", { style: stackStyle, children: [_jsxs("div", { style: brandStyle, children: [_jsx("img", { alt: "", src: logoSrc, style: logoStyle }), _jsx("img", { alt: "OpenAI OAuth", src: wordmarkSrc, style: wordmarkStyle })] }), _jsxs("div", { children: [_jsx("h1", { id: "openai-oauth-extension-title", style: titleStyle, children: "Sign in with ChatGPT" }), _jsxs("p", { style: leadStyle, children: ["A Chrome extension is required", _jsx("br", {}), "to securely sign in."] })] }), _jsxs("ul", { style: listStyle, children: [_jsxs("li", { style: itemStyle, children: [_jsx(CheckIcon, {}), _jsx("span", { children: "Only works after you sign in" })] }), _jsxs("li", { style: itemStyle, children: [_jsx(CheckIcon, {}), _jsx("span", { children: "Never reads your browsing" })] }), _jsxs("li", { style: itemStyle, children: [_jsx(CheckIcon, {}), _jsxs("span", { children: ["Free and", " ", _jsxs("a", { href: defaultGithubUrl, rel: "noreferrer", style: sourceLinkStyle, target: "_blank", children: ["open source", _jsx("span", { "aria-hidden": "true", style: sourceArrowStyle, children: "\u2197" })] })] })] })] }), _jsxs("div", { style: actionsStyle, children: [_jsx("button", { onClick: handlePrimaryClick, style: primaryButtonStyle, type: "button", children: "Continue to Chrome Web Store" }), _jsx("button", { onClick: handleCancelClick, style: secondaryButtonStyle, type: "button", children: "Cancel" }), _jsx("p", { "aria-live": "polite", style: statusStyle, children: status })] })] }), _jsxs("footer", { style: footerStyle, children: [_jsx("a", { href: defaultGithubUrl, rel: "noreferrer", style: linkStyle, target: "_blank", children: "Learn more about OpenAI OAuth" }), _jsxs("div", { style: footerLinksStyle, children: [_jsx("a", { href: defaultGithubUrl, rel: "noreferrer", style: linkStyle, target: "_blank", children: "GitHub" }), _jsx("span", { "aria-hidden": "true", children: "\u22C5" }), _jsx("a", { href: defaultLegalUrl, rel: "noreferrer", style: linkStyle, target: "_blank", children: "Legal" })] })] })] }));
244
+ };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { type BrowserSessionOptions, type BrowserSessionStoreOptions, createSessionStore, getSession, type OpenAIAuthHeadersOptions, openaiAuthHeaders, } from "@openai-oauth/web";
1
+ export { type BrowserSessionOptions, type BrowserSessionStoreOptions, createSessionStore, getSession, type OpenAIAuthHeaders, type OpenAIAuthHeadersOptions, openaiAuthHeaders, } from "@openai-oauth/web";
2
2
  export { SignInWithChatGPT, type SignInWithChatGPTProps, } from "./SignInWithChatGPT.js";
3
3
  export type { OpenAIOAuthSession, SessionStore, SignInWithChatGPTError, SignInWithChatGPTState, } from "./types.js";
4
4
  export { type SignInWithChatGPTOpenMode, type UseSignInWithChatGPTOptions, type UseSignInWithChatGPTReturn, useSignInWithChatGPT, } from "./useSignInWithChatGPT.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,KAAK,qBAAqB,EAC1B,KAAK,0BAA0B,EAC/B,kBAAkB,EAClB,UAAU,EACV,KAAK,wBAAwB,EAC7B,iBAAiB,GACjB,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EACN,iBAAiB,EACjB,KAAK,sBAAsB,GAC3B,MAAM,wBAAwB,CAAA;AAC/B,YAAY,EACX,kBAAkB,EAClB,YAAY,EACZ,sBAAsB,EACtB,sBAAsB,GACtB,MAAM,YAAY,CAAA;AACnB,OAAO,EACN,KAAK,yBAAyB,EAC9B,KAAK,2BAA2B,EAChC,KAAK,0BAA0B,EAC/B,oBAAoB,GACpB,MAAM,2BAA2B,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,KAAK,qBAAqB,EAC1B,KAAK,0BAA0B,EAC/B,kBAAkB,EAClB,UAAU,EACV,KAAK,iBAAiB,EACtB,KAAK,wBAAwB,EAC7B,iBAAiB,GACjB,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EACN,iBAAiB,EACjB,KAAK,sBAAsB,GAC3B,MAAM,wBAAwB,CAAA;AAC/B,YAAY,EACX,kBAAkB,EAClB,YAAY,EACZ,sBAAsB,EACtB,sBAAsB,GACtB,MAAM,YAAY,CAAA;AACnB,OAAO,EACN,KAAK,yBAAyB,EAC9B,KAAK,2BAA2B,EAChC,KAAK,0BAA0B,EAC/B,oBAAoB,GACpB,MAAM,2BAA2B,CAAA"}
package/dist/types.d.ts CHANGED
@@ -17,6 +17,11 @@ export type SignInWithChatGPTState = {
17
17
  status: "starting";
18
18
  session: null;
19
19
  error: null;
20
+ } | {
21
+ status: "needs-extension";
22
+ installUrl: string;
23
+ session: null;
24
+ error: null;
20
25
  } | {
21
26
  status: "redirecting";
22
27
  session: null;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAE1E,YAAY,EAAE,kBAAkB,EAAE,YAAY,EAAE,CAAA;AAEhD,MAAM,MAAM,sBAAsB,GAAG;IACpC,IAAI,EACD,kBAAkB,GAClB,eAAe,GACf,gBAAgB,GAChB,mBAAmB,CAAA;IACtB,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,CAAC,EAAE,OAAO,CAAA;CACf,CAAA;AAED,MAAM,MAAM,sBAAsB,GAC/B;IACA,MAAM,EAAE,UAAU,CAAA;IAClB,OAAO,EAAE,IAAI,CAAA;IACb,KAAK,EAAE,IAAI,CAAA;CACV,GACD;IACA,MAAM,EAAE,YAAY,CAAA;IACpB,OAAO,EAAE,IAAI,CAAA;IACb,KAAK,EAAE,IAAI,CAAA;CACV,GACD;IACA,MAAM,EAAE,UAAU,CAAA;IAClB,OAAO,EAAE,IAAI,CAAA;IACb,KAAK,EAAE,IAAI,CAAA;CACV,GACD;IACA,MAAM,EAAE,aAAa,CAAA;IACrB,OAAO,EAAE,IAAI,CAAA;IACb,KAAK,EAAE,IAAI,CAAA;CACV,GACD;IACA,MAAM,EAAE,WAAW,CAAA;IACnB,OAAO,EAAE,kBAAkB,CAAA;IAC3B,KAAK,EAAE,IAAI,CAAA;CACV,GACD;IACA,MAAM,EAAE,OAAO,CAAA;IACf,OAAO,EAAE,IAAI,CAAA;IACb,KAAK,EAAE,sBAAsB,CAAA;CAC5B,CAAA"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAE1E,YAAY,EAAE,kBAAkB,EAAE,YAAY,EAAE,CAAA;AAEhD,MAAM,MAAM,sBAAsB,GAAG;IACpC,IAAI,EACD,kBAAkB,GAClB,eAAe,GACf,gBAAgB,GAChB,mBAAmB,CAAA;IACtB,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,CAAC,EAAE,OAAO,CAAA;CACf,CAAA;AAED,MAAM,MAAM,sBAAsB,GAC/B;IACA,MAAM,EAAE,UAAU,CAAA;IAClB,OAAO,EAAE,IAAI,CAAA;IACb,KAAK,EAAE,IAAI,CAAA;CACV,GACD;IACA,MAAM,EAAE,YAAY,CAAA;IACpB,OAAO,EAAE,IAAI,CAAA;IACb,KAAK,EAAE,IAAI,CAAA;CACV,GACD;IACA,MAAM,EAAE,UAAU,CAAA;IAClB,OAAO,EAAE,IAAI,CAAA;IACb,KAAK,EAAE,IAAI,CAAA;CACV,GACD;IACA,MAAM,EAAE,iBAAiB,CAAA;IACzB,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,EAAE,IAAI,CAAA;IACb,KAAK,EAAE,IAAI,CAAA;CACV,GACD;IACA,MAAM,EAAE,aAAa,CAAA;IACrB,OAAO,EAAE,IAAI,CAAA;IACb,KAAK,EAAE,IAAI,CAAA;CACV,GACD;IACA,MAAM,EAAE,WAAW,CAAA;IACnB,OAAO,EAAE,kBAAkB,CAAA;IAC3B,KAAK,EAAE,IAAI,CAAA;CACV,GACD;IACA,MAAM,EAAE,OAAO,CAAA;IACf,OAAO,EAAE,IAAI,CAAA;IACb,KAAK,EAAE,sBAAsB,CAAA;CAC5B,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"useSignInWithChatGPT.d.ts","sourceRoot":"","sources":["../src/useSignInWithChatGPT.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,KAAK,oBAAoB,EAKzB,KAAK,iBAAiB,EAEtB,MAAM,mBAAmB,CAAA;AAE1B,OAAO,KAAK,EACX,kBAAkB,EAClB,YAAY,EACZ,sBAAsB,EACtB,sBAAsB,EACtB,MAAM,YAAY,CAAA;AAEnB,MAAM,MAAM,yBAAyB,GAAG,UAAU,GAAG,OAAO,CAAA;AAE5D,MAAM,MAAM,2BAA2B,GAAG,IAAI,CAAC,iBAAiB,EAAE,UAAU,CAAC,GAC5E,IAAI,CAAC,oBAAoB,EAAE,OAAO,GAAG,KAAK,GAAG,UAAU,CAAC,GAAG;IAC1D,YAAY,CAAC,EAAE,YAAY,CAAA;IAC3B,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,sBAAsB,KAAK,IAAI,CAAA;IACvD,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,kBAAkB,KAAK,IAAI,CAAA;IACjD,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,sBAAsB,KAAK,IAAI,CAAA;CACjD,CAAA;AAEF,MAAM,MAAM,0BAA0B,GAAG,sBAAsB,GAAG;IACjE,UAAU,EAAE,OAAO,CAAA;IACnB,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IAC1B,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IAC3B,OAAO,EAAE,MAAM,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAAA;IACjD,KAAK,EAAE,MAAM,IAAI,CAAA;CACjB,CAAA;AA4CD,eAAO,MAAM,oBAAoB,GAChC,UAAS,2BAAgC,KACvC,0BA2QF,CAAA"}
1
+ {"version":3,"file":"useSignInWithChatGPT.d.ts","sourceRoot":"","sources":["../src/useSignInWithChatGPT.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,KAAK,oBAAoB,EAKzB,KAAK,iBAAiB,EAEtB,MAAM,mBAAmB,CAAA;AAE1B,OAAO,KAAK,EACX,kBAAkB,EAClB,YAAY,EACZ,sBAAsB,EACtB,sBAAsB,EACtB,MAAM,YAAY,CAAA;AAEnB,MAAM,MAAM,yBAAyB,GAAG,UAAU,GAAG,OAAO,CAAA;AAE5D,MAAM,MAAM,2BAA2B,GAAG,IAAI,CAAC,iBAAiB,EAAE,UAAU,CAAC,GAC5E,IAAI,CAAC,oBAAoB,EAAE,OAAO,GAAG,KAAK,GAAG,UAAU,CAAC,GAAG;IAC1D,YAAY,CAAC,EAAE,YAAY,CAAA;IAC3B,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,sBAAsB,KAAK,IAAI,CAAA;IACvD,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,kBAAkB,KAAK,IAAI,CAAA;IACjD,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,sBAAsB,KAAK,IAAI,CAAA;CACjD,CAAA;AAEF,MAAM,MAAM,0BAA0B,GAAG,sBAAsB,GAAG;IACjE,UAAU,EAAE,OAAO,CAAA;IACnB,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IAC1B,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IAC3B,OAAO,EAAE,MAAM,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAAA;IACjD,KAAK,EAAE,MAAM,IAAI,CAAA;CACjB,CAAA;AAmDD,eAAO,MAAM,oBAAoB,GAChC,UAAS,2BAAgC,KACvC,0BAsRF,CAAA"}
@@ -11,6 +11,12 @@ const signedOutState = {
11
11
  session: null,
12
12
  error: null,
13
13
  };
14
+ const needsExtensionState = (installUrl) => ({
15
+ status: "needs-extension",
16
+ installUrl,
17
+ session: null,
18
+ error: null,
19
+ });
14
20
  const isBrowser = () => typeof window !== "undefined";
15
21
  const toLoginError = (error, code = "request-failed") => ({
16
22
  code,
@@ -29,7 +35,7 @@ const useLatest = (value) => {
29
35
  return ref;
30
36
  };
31
37
  export const useSignInWithChatGPT = (options = {}) => {
32
- const { callbackPath = "/auth/callback", clientId, codeVerifier, sessionStore: providedSessionStore, extraParams, fetch: fetchImpl, idTokenAddOrganizations, issuer, now, onSuccess, onError, onStateChange, openMode = "redirect", redirectUri, scope, simplifiedFlow, state: configuredState, tokenUrl, } = options;
38
+ const { callbackPath, clientId, codeVerifier, sessionStore: providedSessionStore, extraParams, fetch: fetchImpl, idTokenAddOrganizations, issuer, now, onSuccess, onError, onStateChange, openMode = "redirect", redirectUri, scope, simplifiedFlow, state: configuredState, tokenUrl, } = options;
33
39
  const onSuccessRef = useLatest(onSuccess);
34
40
  const onErrorRef = useLatest(onError);
35
41
  const onStateChangeRef = useLatest(onStateChange);
@@ -141,12 +147,14 @@ export const useSignInWithChatGPT = (options = {}) => {
141
147
  return;
142
148
  }
143
149
  try {
144
- setLoginState({
145
- status: "starting",
146
- session: null,
147
- error: null,
148
- });
149
- await startLogin({
150
+ if (state.status !== "needs-extension") {
151
+ setLoginState({
152
+ status: "starting",
153
+ session: null,
154
+ error: null,
155
+ });
156
+ }
157
+ const result = await startLogin({
150
158
  callbackPath,
151
159
  clientId,
152
160
  codeVerifier,
@@ -159,6 +167,10 @@ export const useSignInWithChatGPT = (options = {}) => {
159
167
  simplifiedFlow,
160
168
  state: configuredState,
161
169
  });
170
+ if (result.status === "needs-extension") {
171
+ setLoginState(needsExtensionState(result.installUrl));
172
+ return;
173
+ }
162
174
  setLoginState({
163
175
  status: "redirecting",
164
176
  session: null,
@@ -185,6 +197,7 @@ export const useSignInWithChatGPT = (options = {}) => {
185
197
  scope,
186
198
  setLoginState,
187
199
  simplifiedFlow,
200
+ state.status,
188
201
  ]);
189
202
  const logout = useCallback(async () => {
190
203
  await clearLogin({ sessionStore });
@@ -206,11 +219,14 @@ export const useSignInWithChatGPT = (options = {}) => {
206
219
  now,
207
220
  tokenUrl,
208
221
  });
209
- await sessionStore.set(refreshed);
210
- const next = signedInState(refreshed);
222
+ const nextSession = session.isFedRamp && !refreshed.isFedRamp
223
+ ? { ...refreshed, isFedRamp: true }
224
+ : refreshed;
225
+ await sessionStore.set(nextSession);
226
+ const next = signedInState(nextSession);
211
227
  setLoginState(next);
212
- onSuccessRef.current?.(refreshed);
213
- return refreshed;
228
+ onSuccessRef.current?.(nextSession);
229
+ return nextSession;
214
230
  }
215
231
  catch (error) {
216
232
  fail(error);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openai-oauth/react",
3
- "version": "2.0.0-beta.0",
3
+ "version": "2.0.0-beta.2",
4
4
  "description": "React hook and button for OpenAI OAuth sessions.",
5
5
  "keywords": [
6
6
  "openai",
@@ -44,8 +44,8 @@
44
44
  "react": ">=18.2.0 || >=19.0.0"
45
45
  },
46
46
  "dependencies": {
47
- "@openai-oauth/core": "2.0.0-beta.0",
48
- "@openai-oauth/web": "2.0.0-beta.0"
47
+ "@openai-oauth/core": "2.0.0-beta.2",
48
+ "@openai-oauth/web": "2.0.0-beta.2"
49
49
  },
50
50
  "devDependencies": {
51
51
  "@types/react": "^19.0.0",
package/dist/next.d.ts DELETED
@@ -1,4 +0,0 @@
1
- export declare const GET: (request: Request) => Promise<Response>;
2
- export declare const POST: (request: Request) => Promise<Response>;
3
- export declare const OPTIONS: (request: Request) => Promise<Response>;
4
- //# sourceMappingURL=next.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"next.d.ts","sourceRoot":"","sources":["../src/next.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,GAAG,GAAI,SAAS,OAAO,KAAG,OAAO,CAAC,QAAQ,CAAqB,CAAA;AAC5E,eAAO,MAAM,IAAI,GAAI,SAAS,OAAO,KAAG,OAAO,CAAC,QAAQ,CAAqB,CAAA;AAC7E,eAAO,MAAM,OAAO,GAAI,SAAS,OAAO,KAAG,OAAO,CAAC,QAAQ,CAAqB,CAAA"}
package/dist/next.js DELETED
@@ -1,5 +0,0 @@
1
- import { createRelayHandler } from "@openai-oauth/web";
2
- const handler = createRelayHandler();
3
- export const GET = (request) => handler(request);
4
- export const POST = (request) => handler(request);
5
- export const OPTIONS = (request) => handler(request);