@donotdev/oauth 0.0.7 → 0.0.8
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/components/MultipleOAuthProviders.d.ts +0 -8
- package/dist/components/MultipleOAuthProviders.d.ts.map +1 -1
- package/dist/components/MultipleOAuthProviders.js +1 -1
- package/dist/components/OAuthConnectionModal.js +1 -1
- package/dist/components/OAuthFallback.js +1 -1
- package/dist/components/OAuthPartnerButton.d.ts.map +1 -1
- package/dist/components/OAuthPartnerButton.js +1 -1
- package/dist/config/oauthConfigUtils.d.ts +0 -20
- package/dist/config/oauthConfigUtils.d.ts.map +1 -1
- package/dist/config/oauthConfigUtils.js +1 -1
- package/dist/config/schemas.js +1 -1
- package/dist/index.js +1 -1
- package/dist/oauthStore.d.ts +1 -1
- package/dist/oauthStore.d.ts.map +1 -1
- package/dist/oauthStore.js +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/useOAuth.d.ts +10 -4
- package/dist/useOAuth.d.ts.map +1 -1
- package/dist/useOAuth.js +1 -1
- package/dist/utils/partner-discovery.js +1 -1
- package/package.json +4 -4
package/dist/useOAuth.d.ts
CHANGED
|
@@ -8,18 +8,24 @@ import type { OAuthAPI } from '@donotdev/core';
|
|
|
8
8
|
* **Property-based access (clean and simple):**
|
|
9
9
|
* ```typescript
|
|
10
10
|
* // ✅ State from store (reactive, re-renders on change)
|
|
11
|
-
* const
|
|
11
|
+
* const status = useOAuth('status');
|
|
12
12
|
* const error = useOAuth('error');
|
|
13
13
|
* const partners = useOAuth('partners');
|
|
14
|
+
* const connectedPartners = useOAuth('connectedPartners');
|
|
15
|
+
* const isAvailable = useOAuth('isAvailable');
|
|
14
16
|
*
|
|
15
|
-
* // ✅ Methods
|
|
17
|
+
* // ✅ Methods (stable, never re-renders)
|
|
16
18
|
* const connect = useOAuth('connect');
|
|
17
19
|
* await connect('github', 'api-access');
|
|
20
|
+
* const disconnect = useOAuth('disconnect');
|
|
21
|
+
* const handleCallback = useOAuth('handleCallback');
|
|
22
|
+
* const isConnected = useOAuth('isConnected');
|
|
23
|
+
* const getCredentials = useOAuth('getCredentials');
|
|
18
24
|
* ```
|
|
19
25
|
*
|
|
20
26
|
* **How it works:**
|
|
21
|
-
* - Store properties (
|
|
22
|
-
* - Methods (connect, disconnect,
|
|
27
|
+
* - Store properties (status, error, partners, connectedPartners) → Subscribe via Zustand (reactive)
|
|
28
|
+
* - Methods (connect, disconnect, handleCallback, isConnected, getCredentials) → useCallback (stable)
|
|
23
29
|
*
|
|
24
30
|
* @template K - The property key from OAuthAPI
|
|
25
31
|
* @param key - Property name to access
|
package/dist/useOAuth.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useOAuth.d.ts","sourceRoot":"","sources":["../src/useOAuth.ts"],"names":[],"mappings":"AA0BA,OAAO,KAAK,EACV,QAAQ,EAIT,MAAM,gBAAgB,CAAC;AAmBxB
|
|
1
|
+
{"version":3,"file":"useOAuth.d.ts","sourceRoot":"","sources":["../src/useOAuth.ts"],"names":[],"mappings":"AA0BA,OAAO,KAAK,EACV,QAAQ,EAIT,MAAM,gBAAgB,CAAC;AAmBxB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDG;AACH,wBAAgB,QAAQ,CAAC,CAAC,SAAS,MAAM,QAAQ,EAAE,GAAG,EAAE,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAyQtE"}
|
package/dist/useOAuth.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";import{useCallback as
|
|
1
|
+
"use client";import{useCallback as m}from"react";import{DEGRADED_OAUTH_API as I,FRAMEWORK_FEATURES as F,getOAuthClientId as T,getOAuthPartnerConfig as b,getOAuthRedirectUri as k,handleError as y,isClient as h,redirectToExternalUrlWithErrorHandling as R,useFeatureConsent as U}from"@donotdev/core";import{useOAuthStore as a}from"./oauthStore";let E=!1,A=!1,C=!1;const v=new Set(["status","error","partners","connectedPartners"]);function L(t){const r=U(F.OAUTH),c=m(async(e,s="api-access")=>{if(!h()||!r)return;const i=a.getState();i.setLoading(!0),i.setError(null),i.setPartnerConnecting(e,!0);try{const n=T(e);if(!n)throw new Error(`${e.toUpperCase()}_CLIENT_ID not configured`);const o=k(e),{codeChallenge:u,codeVerifier:f}=await x(),S=`${e}_${P(32)}`,O=j(e,n,o,u,s,S);sessionStorage.setItem(`oauth_state_${e}`,S),sessionStorage.setItem(`oauth_purpose_${e}`,s),sessionStorage.setItem(`oauth_${e}_verifier`,f),await R(O,{},"Failed to redirect to OAuth provider");const $=a.getState();$.setLoading(!1),$.setPartnerConnecting(e,!1),E=!1}catch(n){const o=a.getState();o.setLoading(!1),o.setPartnerConnecting(e,!1);const u=n instanceof Error?n.message:"Failed to connect";E||(y(n,{userMessage:`Failed to connect to ${e}. Please try again.`,context:{partnerId:e},severity:"error"}),E=!0),o.setPartnerError(e,u)}},[r]),g=m(async e=>{if(!h()||!r)return;const s=a.getState();s.setLoading(!0),s.setError(null);try{s.setPartnerDisconnected(e),sessionStorage.removeItem(`oauth_${e}_verifier`),sessionStorage.removeItem(`oauth_${e}_credentials`),sessionStorage.removeItem(`oauth_state_${e}`),sessionStorage.removeItem(`oauth_purpose_${e}`),A=!1}catch(i){const n=a.getState(),o=i instanceof Error?i.message:"Failed to disconnect";A||(y(i,{userMessage:`Failed to disconnect from ${e}. Please try again.`,context:{partnerId:e},severity:"error"}),A=!0),n.setPartnerError(e,o)}finally{a.getState().setLoading(!1)}},[r]),d=m(async(e,s,i)=>{if(!h()||!r)return;const n=a.getState();n.setLoading(!0),n.setError(null);try{const o=sessionStorage.getItem(`oauth_state_${e}`);if(!o)throw new Error("OAuth state not found \u2014 possible CSRF attack");if(!o.startsWith(`${e}_`))throw new Error("OAuth state partnerId mismatch \u2014 possible CSRF attack");if(!i||i!==o)throw new Error("OAuth state mismatch \u2014 possible CSRF attack");sessionStorage.removeItem(`oauth_state_${e}`);const u=sessionStorage.getItem(`oauth_${e}_verifier`);if(!u)throw new Error("OAuth code verifier not found");const f=await D(e,s,u),S=sessionStorage.getItem(`oauth_purpose_${e}`)||"api-access";sessionStorage.removeItem(`oauth_purpose_${e}`),n.setPartnerConnected(e,f,S),sessionStorage.removeItem(`oauth_${e}_verifier`),C=!1}catch(o){const u=a.getState(),f=o instanceof Error?o.message:"Failed to handle callback";C||(y(o,{userMessage:`Failed to complete ${e} authentication. Please try again.`,context:{partnerId:e},severity:"error"}),C=!0),u.setPartnerError(e,f)}finally{a.getState().setLoading(!1)}},[r]),w=m(e=>!h()||!r?!1:a.getState().isConnected(e),[r]),l=m(e=>!h()||!r?null:a.getState().getCredentials(e),[r]),p={connect:c,disconnect:g,handleCallback:d,isConnected:w,getCredentials:l},_=a(e=>v.has(t)?t==="connectedPartners"?e.getConnectedPartners():e[t]:null);return!h()||!r?I[t]:t==="isAvailable"?!0:v.has(t)?_:t in p?p[t]:I[t]}async function x(){const t=P(128),r=new TextEncoder().encode(t),c=await crypto.subtle.digest("SHA-256",r);return{codeVerifier:t,codeChallenge:btoa(String.fromCharCode(...new Uint8Array(c))).replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")}}function P(t){const r="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~",c=crypto.getRandomValues(new Uint8Array(t));return Array.from(c,g=>r[g%r.length]).join("")}function j(t,r,c,g,d,w){const l=b(t);if(!l)throw new Error(`OAuth partner ${t} not configured`);const p=l.endpoints.authUrl;if(!p)throw new Error(`OAuth partner ${t} has no auth URL configured`);const _=l.scopes[d]||l.scopes["api-access"]||[],e=Array.isArray(_)?_.join(" "):"",s=new URLSearchParams({client_id:r,redirect_uri:c,response_type:"code",scope:e,state:w,code_challenge:g,code_challenge_method:"S256"});return`${p}?${s.toString()}`}async function D(t,r,c){const g=await fetch("/api/oauth/exchange",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({partnerId:t,code:r,codeVerifier:c})});if(!g.ok)throw new Error("Token exchange failed");const d=await g.json();if(typeof d!="object"||d===null||typeof d.accessToken!="string"||d.accessToken==="")throw new Error("Token exchange returned invalid credentials");return d}export{L as useOAuth};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{OAUTH_PARTNERS as
|
|
1
|
+
import{OAUTH_PARTNERS as u,getEnabledOAuthPartners as c}from"@donotdev/core";function s(){return Object.keys(u)}function a(){return c()}function i(){const n=a();return s().filter(t=>!n.includes(t))}function o(n){return u[n]}function h(n){const t=u[n];return t?`${t.name}OAuthButton`:""}function l(){s().forEach(n=>{const t=h(n),e=a().includes(n)})}function g(){const n=[],t=s();return t.forEach(e=>{const r=o(e);if(!r){n.push(`Partner '${e}' has no configuration`);return}r.name||n.push(`Partner '${e}' missing name`),r.endpoints?.authUrl||n.push(`Partner '${e}' missing auth URL`),r.endpoints?.tokenUrl||n.push(`Partner '${e}' missing token URL`),r.icon||n.push(`Partner '${e}' missing icon`)}),{isValid:n.length===0,issues:n,totalPartners:t.length,enabledPartners:a().length,disabledPartners:i().length}}export{s as getAllOAuthPartners,i as getDisabledOAuthPartners,a as getEnabledOAuthPartners,h as getOAuthPartnerButtonName,o as getOAuthPartnerConfig,l as logOAuthPartnerDiscovery,g as validateOAuthPartnerIntegrity};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@donotdev/oauth",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.8",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "SEE LICENSE IN LICENSE.md",
|
|
@@ -24,14 +24,14 @@
|
|
|
24
24
|
"scripts": {
|
|
25
25
|
"dev": "tsc --noEmit --watch --listFiles false --listEmittedFiles false",
|
|
26
26
|
"clean": "rimraf dist tsconfig.tsbuildinfo",
|
|
27
|
-
"type-check": "tsc --noEmit"
|
|
27
|
+
"type-check": "bunx tsc --noEmit"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"valibot": "^1.2.0"
|
|
31
31
|
},
|
|
32
32
|
"peerDependencies": {
|
|
33
|
-
"@donotdev/components": "^0.0.
|
|
34
|
-
"@donotdev/core": "^0.0.
|
|
33
|
+
"@donotdev/components": "^0.0.19",
|
|
34
|
+
"@donotdev/core": "^0.0.25",
|
|
35
35
|
"firebase": "^12.5.0",
|
|
36
36
|
"react": "^19.2.4",
|
|
37
37
|
"react-dom": "^19.2.4"
|