@zoneout/sdk 0.1.0

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.
Files changed (103) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +124 -0
  3. package/dist/cjs/client.d.ts +53 -0
  4. package/dist/cjs/client.d.ts.map +1 -0
  5. package/dist/cjs/client.js +141 -0
  6. package/dist/cjs/client.js.map +1 -0
  7. package/dist/cjs/errors.d.ts +7 -0
  8. package/dist/cjs/errors.d.ts.map +1 -0
  9. package/dist/cjs/errors.js +13 -0
  10. package/dist/cjs/errors.js.map +1 -0
  11. package/dist/cjs/index.d.ts +7 -0
  12. package/dist/cjs/index.d.ts.map +1 -0
  13. package/dist/cjs/index.js +19 -0
  14. package/dist/cjs/index.js.map +1 -0
  15. package/dist/cjs/pkce.d.ts +4 -0
  16. package/dist/cjs/pkce.d.ts.map +1 -0
  17. package/dist/cjs/pkce.js +30 -0
  18. package/dist/cjs/pkce.js.map +1 -0
  19. package/dist/cjs/polling.d.ts +15 -0
  20. package/dist/cjs/polling.d.ts.map +1 -0
  21. package/dist/cjs/polling.js +53 -0
  22. package/dist/cjs/polling.js.map +1 -0
  23. package/dist/cjs/react/index.d.ts +3 -0
  24. package/dist/cjs/react/index.d.ts.map +1 -0
  25. package/dist/cjs/react/index.js +9 -0
  26. package/dist/cjs/react/index.js.map +1 -0
  27. package/dist/cjs/react/provider.d.ts +11 -0
  28. package/dist/cjs/react/provider.d.ts.map +1 -0
  29. package/dist/cjs/react/provider.js +24 -0
  30. package/dist/cjs/react/provider.js.map +1 -0
  31. package/dist/cjs/react/use-zoneout.d.ts +25 -0
  32. package/dist/cjs/react/use-zoneout.d.ts.map +1 -0
  33. package/dist/cjs/react/use-zoneout.js +60 -0
  34. package/dist/cjs/react/use-zoneout.js.map +1 -0
  35. package/dist/cjs/server.d.ts +12 -0
  36. package/dist/cjs/server.d.ts.map +1 -0
  37. package/dist/cjs/server.js +58 -0
  38. package/dist/cjs/server.js.map +1 -0
  39. package/dist/cjs/types.d.ts +85 -0
  40. package/dist/cjs/types.d.ts.map +1 -0
  41. package/dist/cjs/types.js +4 -0
  42. package/dist/cjs/types.js.map +1 -0
  43. package/dist/esm/client.d.ts +53 -0
  44. package/dist/esm/client.d.ts.map +1 -0
  45. package/dist/esm/client.js +137 -0
  46. package/dist/esm/client.js.map +1 -0
  47. package/dist/esm/errors.d.ts +7 -0
  48. package/dist/esm/errors.d.ts.map +1 -0
  49. package/dist/esm/errors.js +9 -0
  50. package/dist/esm/errors.js.map +1 -0
  51. package/dist/esm/index.d.ts +7 -0
  52. package/dist/esm/index.d.ts.map +1 -0
  53. package/dist/esm/index.js +9 -0
  54. package/dist/esm/index.js.map +1 -0
  55. package/dist/esm/pkce.d.ts +4 -0
  56. package/dist/esm/pkce.d.ts.map +1 -0
  57. package/dist/esm/pkce.js +25 -0
  58. package/dist/esm/pkce.js.map +1 -0
  59. package/dist/esm/polling.d.ts +15 -0
  60. package/dist/esm/polling.d.ts.map +1 -0
  61. package/dist/esm/polling.js +50 -0
  62. package/dist/esm/polling.js.map +1 -0
  63. package/dist/esm/react/index.d.ts +3 -0
  64. package/dist/esm/react/index.d.ts.map +1 -0
  65. package/dist/esm/react/index.js +3 -0
  66. package/dist/esm/react/index.js.map +1 -0
  67. package/dist/esm/react/provider.d.ts +11 -0
  68. package/dist/esm/react/provider.d.ts.map +1 -0
  69. package/dist/esm/react/provider.js +20 -0
  70. package/dist/esm/react/provider.js.map +1 -0
  71. package/dist/esm/react/use-zoneout.d.ts +25 -0
  72. package/dist/esm/react/use-zoneout.d.ts.map +1 -0
  73. package/dist/esm/react/use-zoneout.js +57 -0
  74. package/dist/esm/react/use-zoneout.js.map +1 -0
  75. package/dist/esm/server.d.ts +12 -0
  76. package/dist/esm/server.d.ts.map +1 -0
  77. package/dist/esm/server.js +54 -0
  78. package/dist/esm/server.js.map +1 -0
  79. package/dist/esm/types.d.ts +85 -0
  80. package/dist/esm/types.d.ts.map +1 -0
  81. package/dist/esm/types.js +3 -0
  82. package/dist/esm/types.js.map +1 -0
  83. package/dist/types/client.d.ts +53 -0
  84. package/dist/types/client.d.ts.map +1 -0
  85. package/dist/types/errors.d.ts +7 -0
  86. package/dist/types/errors.d.ts.map +1 -0
  87. package/dist/types/index.d.ts +7 -0
  88. package/dist/types/index.d.ts.map +1 -0
  89. package/dist/types/pkce.d.ts +4 -0
  90. package/dist/types/pkce.d.ts.map +1 -0
  91. package/dist/types/polling.d.ts +15 -0
  92. package/dist/types/polling.d.ts.map +1 -0
  93. package/dist/types/react/index.d.ts +3 -0
  94. package/dist/types/react/index.d.ts.map +1 -0
  95. package/dist/types/react/provider.d.ts +11 -0
  96. package/dist/types/react/provider.d.ts.map +1 -0
  97. package/dist/types/react/use-zoneout.d.ts +25 -0
  98. package/dist/types/react/use-zoneout.d.ts.map +1 -0
  99. package/dist/types/server.d.ts +12 -0
  100. package/dist/types/server.d.ts.map +1 -0
  101. package/dist/types/types.d.ts +85 -0
  102. package/dist/types/types.d.ts.map +1 -0
  103. package/package.json +68 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-zoneout.d.ts","sourceRoot":"","sources":["../../../src/react/use-zoneout.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAGjD,UAAU,gBAAgB;IACxB,qDAAqD;IACrD,aAAa,EAAE,MAAM,OAAO,CAAC;QAC3B,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;QAClB,eAAe,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;QACrC,KAAK,EAAE,eAAe,CAAC;KACxB,CAAC,CAAC;IACH,wCAAwC;IACxC,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3B,oBAAoB;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,uDAAuD;IACvD,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,8BAA8B;IAC9B,KAAK,EAAE;QAAE,IAAI,EAAE,gBAAgB,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CAC3D;AAED,wBAAgB,UAAU,IAAI,gBAAgB,CAsD7C"}
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useZoneOut = useZoneOut;
4
+ const react_1 = require("react");
5
+ const provider_1 = require("./provider");
6
+ function useZoneOut() {
7
+ const client = (0, provider_1.useZoneOutClient)();
8
+ const [isLoading, setIsLoading] = (0, react_1.useState)(false);
9
+ const [qrCodeUrl, setQrCodeUrl] = (0, react_1.useState)(null);
10
+ const [error, setError] = (0, react_1.useState)(null);
11
+ const initiateLogin = (0, react_1.useCallback)(async () => {
12
+ setIsLoading(true);
13
+ setError(null);
14
+ setQrCodeUrl(null);
15
+ try {
16
+ const result = await client.initiateLogin();
17
+ setQrCodeUrl(result.qrCodeUrl);
18
+ return {
19
+ ...result,
20
+ waitForApproval: async () => {
21
+ try {
22
+ const status = await result.waitForApproval();
23
+ if (status.authorization_code) {
24
+ window.location.href = client.buildCallbackUrl(status.authorization_code);
25
+ }
26
+ }
27
+ catch (err) {
28
+ const e = err;
29
+ setError({ code: e.code ?? 'UNKNOWN_ERROR', message: e.message });
30
+ throw err;
31
+ }
32
+ finally {
33
+ setIsLoading(false);
34
+ }
35
+ },
36
+ };
37
+ }
38
+ catch (err) {
39
+ const e = err;
40
+ setError({ code: e.code ?? 'UNKNOWN_ERROR', message: e.message });
41
+ setIsLoading(false);
42
+ throw err;
43
+ }
44
+ }, [client]);
45
+ const login = (0, react_1.useCallback)(async () => {
46
+ setIsLoading(true);
47
+ setError(null);
48
+ try {
49
+ await client.login();
50
+ }
51
+ catch (err) {
52
+ const e = err;
53
+ setError({ code: e.code ?? 'UNKNOWN_ERROR', message: e.message });
54
+ setIsLoading(false);
55
+ throw err;
56
+ }
57
+ }, [client]);
58
+ return { initiateLogin, login, isLoading, qrCodeUrl, error };
59
+ }
60
+ //# sourceMappingURL=use-zoneout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-zoneout.js","sourceRoot":"","sources":["../../../src/react/use-zoneout.ts"],"names":[],"mappings":";;AAwBA,gCAsDC;AA9ED,iCAA8C;AAC9C,yCAA8C;AAuB9C,SAAgB,UAAU;IACxB,MAAM,MAAM,GAAG,IAAA,2BAAgB,GAAE,CAAC;IAClC,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,IAAA,gBAAQ,EAAC,KAAK,CAAC,CAAC;IAClD,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,IAAA,gBAAQ,EAAgB,IAAI,CAAC,CAAC;IAChE,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,IAAA,gBAAQ,EAAqD,IAAI,CAAC,CAAC;IAE7F,MAAM,aAAa,GAAG,IAAA,mBAAW,EAAC,KAAK,IAAI,EAAE;QAC3C,YAAY,CAAC,IAAI,CAAC,CAAC;QACnB,QAAQ,CAAC,IAAI,CAAC,CAAC;QACf,YAAY,CAAC,IAAI,CAAC,CAAC;QAEnB,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,aAAa,EAAE,CAAC;YAC5C,YAAY,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;YAE/B,OAAO;gBACL,GAAG,MAAM;gBACT,eAAe,EAAE,KAAK,IAAI,EAAE;oBAC1B,IAAI,CAAC;wBACH,MAAM,MAAM,GAAkB,MAAM,MAAM,CAAC,eAAe,EAAE,CAAC;wBAC7D,IAAI,MAAM,CAAC,kBAAkB,EAAE,CAAC;4BAC9B,MAAM,CAAC,QAAQ,CAAC,IAAI,GAAG,MAAM,CAAC,gBAAgB,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC;wBAC5E,CAAC;oBACH,CAAC;oBAAC,OAAO,GAAY,EAAE,CAAC;wBACtB,MAAM,CAAC,GAAG,GAAmD,CAAC;wBAC9D,QAAQ,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,IAAI,eAAe,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;wBAClE,MAAM,GAAG,CAAC;oBACZ,CAAC;4BAAS,CAAC;wBACT,YAAY,CAAC,KAAK,CAAC,CAAC;oBACtB,CAAC;gBACH,CAAC;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,MAAM,CAAC,GAAG,GAAmD,CAAC;YAC9D,QAAQ,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,IAAI,eAAe,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;YAClE,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;IAEb,MAAM,KAAK,GAAG,IAAA,mBAAW,EAAC,KAAK,IAAI,EAAE;QACnC,YAAY,CAAC,IAAI,CAAC,CAAC;QACnB,QAAQ,CAAC,IAAI,CAAC,CAAC;QACf,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;QACvB,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,MAAM,CAAC,GAAG,GAAmD,CAAC;YAC9D,QAAQ,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,IAAI,eAAe,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;YAClE,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;IAEb,OAAO,EAAE,aAAa,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;AAC/D,CAAC"}
@@ -0,0 +1,12 @@
1
+ import type { TokenExchangeParams, TokenRefreshParams, TokenResponse } from './types';
2
+ /**
3
+ * Scambia l'authorization_code per access_token + refresh_token + user data.
4
+ * Da chiamare SOLO server-side (usa client_secret).
5
+ */
6
+ export declare function exchangeCodeForTokens(params: TokenExchangeParams): Promise<TokenResponse>;
7
+ /**
8
+ * Refresh dell'access_token usando il refresh_token.
9
+ * Da chiamare SOLO server-side (usa client_secret).
10
+ */
11
+ export declare function refreshAccessToken(params: TokenRefreshParams): Promise<TokenResponse>;
12
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAGtF;;;GAGG;AACH,wBAAsB,qBAAqB,CAAC,MAAM,EAAE,mBAAmB,GAAG,OAAO,CAAC,aAAa,CAAC,CA6B/F;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,aAAa,CAAC,CA2B3F"}
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.exchangeCodeForTokens = exchangeCodeForTokens;
4
+ exports.refreshAccessToken = refreshAccessToken;
5
+ const errors_1 = require("./errors");
6
+ /**
7
+ * Scambia l'authorization_code per access_token + refresh_token + user data.
8
+ * Da chiamare SOLO server-side (usa client_secret).
9
+ */
10
+ async function exchangeCodeForTokens(params) {
11
+ const { code, clientId, clientSecret, codeVerifier, redirectUri, authServerUrl, apiKey } = params;
12
+ const res = await fetch(`${authServerUrl}/auth-token`, {
13
+ method: 'POST',
14
+ headers: {
15
+ 'Content-Type': 'application/json',
16
+ ...(apiKey ? { apikey: apiKey, Authorization: `Bearer ${apiKey}` } : {}),
17
+ },
18
+ body: JSON.stringify({
19
+ grant_type: 'authorization_code',
20
+ code,
21
+ client_id: clientId,
22
+ client_secret: clientSecret,
23
+ code_verifier: codeVerifier,
24
+ redirect_uri: redirectUri,
25
+ }),
26
+ });
27
+ if (!res.ok) {
28
+ const body = await res.json().catch(() => ({}));
29
+ throw new errors_1.ZoneOutError('TOKEN_EXCHANGE_FAILED', body.error || `Token exchange failed: HTTP ${res.status}`, body);
30
+ }
31
+ return res.json();
32
+ }
33
+ /**
34
+ * Refresh dell'access_token usando il refresh_token.
35
+ * Da chiamare SOLO server-side (usa client_secret).
36
+ */
37
+ async function refreshAccessToken(params) {
38
+ const { refreshToken, clientId, clientSecret, authServerUrl, apiKey } = params;
39
+ const res = await fetch(`${authServerUrl}/auth-token`, {
40
+ method: 'POST',
41
+ headers: {
42
+ 'Content-Type': 'application/json',
43
+ ...(apiKey ? { apikey: apiKey, Authorization: `Bearer ${apiKey}` } : {}),
44
+ },
45
+ body: JSON.stringify({
46
+ grant_type: 'refresh_token',
47
+ refresh_token: refreshToken,
48
+ client_id: clientId,
49
+ client_secret: clientSecret,
50
+ }),
51
+ });
52
+ if (!res.ok) {
53
+ const body = await res.json().catch(() => ({}));
54
+ throw new errors_1.ZoneOutError('TOKEN_EXCHANGE_FAILED', body.error || `Token refresh failed: HTTP ${res.status}`, body);
55
+ }
56
+ return res.json();
57
+ }
58
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/server.ts"],"names":[],"mappings":";;AAOA,sDA6BC;AAMD,gDA2BC;AApED,qCAAwC;AAExC;;;GAGG;AACI,KAAK,UAAU,qBAAqB,CAAC,MAA2B;IACrE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC;IAElG,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,aAAa,aAAa,EAAE;QACrD,MAAM,EAAE,MAAM;QACd,OAAO,EAAE;YACP,cAAc,EAAE,kBAAkB;YAClC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,UAAU,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACzE;QACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;YACnB,UAAU,EAAE,oBAAoB;YAChC,IAAI;YACJ,SAAS,EAAE,QAAQ;YACnB,aAAa,EAAE,YAAY;YAC3B,aAAa,EAAE,YAAY;YAC3B,YAAY,EAAE,WAAW;SAC1B,CAAC;KACH,CAAC,CAAC;IAEH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAChD,MAAM,IAAI,qBAAY,CACpB,uBAAuB,EACvB,IAAI,CAAC,KAAK,IAAI,+BAA+B,GAAG,CAAC,MAAM,EAAE,EACzD,IAAI,CACL,CAAC;IACJ,CAAC;IAED,OAAO,GAAG,CAAC,IAAI,EAAE,CAAC;AACpB,CAAC;AAED;;;GAGG;AACI,KAAK,UAAU,kBAAkB,CAAC,MAA0B;IACjE,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC;IAE/E,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,aAAa,aAAa,EAAE;QACrD,MAAM,EAAE,MAAM;QACd,OAAO,EAAE;YACP,cAAc,EAAE,kBAAkB;YAClC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,UAAU,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACzE;QACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;YACnB,UAAU,EAAE,eAAe;YAC3B,aAAa,EAAE,YAAY;YAC3B,SAAS,EAAE,QAAQ;YACnB,aAAa,EAAE,YAAY;SAC5B,CAAC;KACH,CAAC,CAAC;IAEH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAChD,MAAM,IAAI,qBAAY,CACpB,uBAAuB,EACvB,IAAI,CAAC,KAAK,IAAI,8BAA8B,GAAG,CAAC,MAAM,EAAE,EACxD,IAAI,CACL,CAAC;IACJ,CAAC;IAED,OAAO,GAAG,CAAC,IAAI,EAAE,CAAC;AACpB,CAAC"}
@@ -0,0 +1,85 @@
1
+ export interface ZoneOutConfig {
2
+ /** client_id ottenuto dalla registrazione su dashboard.zoneout.io */
3
+ clientId: string;
4
+ /** URL base delle Edge Functions Supabase (es: https://xxx.supabase.co/functions/v1) */
5
+ authServerUrl: string;
6
+ /** URI di redirect autorizzato per questo client */
7
+ redirectUri: string;
8
+ /** Supabase anon key — required for Supabase Edge Functions gateway */
9
+ apiKey?: string;
10
+ /** Scope richiesti (default: ["identity"]) */
11
+ scope?: string[];
12
+ /** Timeout polling in ms (default: 300000 = 5 min) */
13
+ pollingTimeout?: number;
14
+ /** Intervallo polling in ms (default: 2000) */
15
+ pollingInterval?: number;
16
+ }
17
+ export interface ZoneOutUser {
18
+ zo_sub: string;
19
+ username: string;
20
+ wallet_address: string | null;
21
+ providers: Record<string, {
22
+ username: string;
23
+ user_id: string;
24
+ }>;
25
+ trust: Record<string, 'unrated' | 'red' | 'yellow' | 'green' | 'blue'>;
26
+ }
27
+ export interface ZoneOutTokens {
28
+ access_token: string;
29
+ refresh_token: string;
30
+ expires_at: number;
31
+ }
32
+ export interface ZoneOutLoginResult {
33
+ user: ZoneOutUser;
34
+ tokens: ZoneOutTokens;
35
+ }
36
+ export type LoginSessionStatus = 'pending_approval' | 'approved' | 'rejected' | 'expired';
37
+ export interface LoginSession {
38
+ login_session_id: string;
39
+ expires_at: string;
40
+ status: LoginSessionStatus;
41
+ }
42
+ export interface LoginSessionDetail {
43
+ id: string;
44
+ client_app_name: string;
45
+ client_app_icon_url: string | null;
46
+ required_providers: string[];
47
+ requested_trust_categories: string[];
48
+ scope: string[];
49
+ status: LoginSessionStatus;
50
+ created_at: string;
51
+ expires_at: string;
52
+ }
53
+ export interface LoginSessionResponse {
54
+ session: LoginSessionDetail;
55
+ authorization_code?: string;
56
+ }
57
+ export interface TokenExchangeParams {
58
+ code: string;
59
+ clientId: string;
60
+ clientSecret: string;
61
+ codeVerifier: string;
62
+ redirectUri: string;
63
+ authServerUrl: string;
64
+ apiKey?: string;
65
+ }
66
+ export interface TokenRefreshParams {
67
+ refreshToken: string;
68
+ clientId: string;
69
+ clientSecret: string;
70
+ authServerUrl: string;
71
+ apiKey?: string;
72
+ }
73
+ export interface TokenResponse {
74
+ access_token: string;
75
+ token_type: string;
76
+ expires_in: number;
77
+ refresh_token: string;
78
+ user?: ZoneOutUser;
79
+ }
80
+ export type ZoneOutEvent = 'login_start' | 'login_approved' | 'login_rejected' | 'login_expired' | 'login_error' | 'logout';
81
+ export interface ZoneOutEventCallback {
82
+ (event: ZoneOutEvent, data?: unknown): void;
83
+ }
84
+ export type ZoneOutErrorCode = 'USER_REJECTED' | 'SESSION_EXPIRED' | 'PROVIDER_MISSING' | 'PROVIDER_LOCKED' | 'DEVICE_NOT_BOUND' | 'INVALID_CLIENT' | 'INVALID_REDIRECT' | 'RATE_LIMITED' | 'NETWORK_ERROR' | 'POLLING_TIMEOUT' | 'TOKEN_EXCHANGE_FAILED' | 'UNKNOWN_ERROR';
85
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ // --- Configurazione ---
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":";AAAA,yBAAyB"}
@@ -0,0 +1,53 @@
1
+ import type { ZoneOutConfig, ZoneOutEvent, ZoneOutEventCallback } from './types';
2
+ import { type PollingResult } from './polling';
3
+ export interface LoginInitResult {
4
+ /** URL del QR code da mostrare all'utente: zoneout://approve?session={id} */
5
+ qrCodeUrl: string;
6
+ /** ID della sessione di login */
7
+ sessionId: string;
8
+ /** Scade a (ISO string) */
9
+ expiresAt: string;
10
+ /** AbortController per annullare il login */
11
+ abort: AbortController;
12
+ /**
13
+ * Promise che si risolve quando l'utente approva.
14
+ * Restituisce il risultato con authorization_code.
15
+ * Il consumer è responsabile del redirect.
16
+ */
17
+ waitForApproval: () => Promise<PollingResult>;
18
+ }
19
+ export declare class ZoneOutClient {
20
+ private config;
21
+ private listeners;
22
+ private _codeVerifier;
23
+ private _state;
24
+ constructor(config: ZoneOutConfig);
25
+ /**
26
+ * Avvia il flusso di login.
27
+ * Restituisce l'URL del QR code e una promise per attendere l'approvazione.
28
+ */
29
+ initiateLogin(): Promise<LoginInitResult>;
30
+ /**
31
+ * Restituisce il code_verifier generato nell'ultimo initiateLogin.
32
+ * Serve al backend per il token exchange.
33
+ * ATTENZIONE: NON inviare mai il code_verifier a terzi. Va solo al TUO backend.
34
+ */
35
+ getCodeVerifier(): string | null;
36
+ /**
37
+ * Restituisce lo state generato nell'ultimo initiateLogin.
38
+ */
39
+ getState(): string | null;
40
+ /**
41
+ * Genera l'URL di redirect al backend del consumer con i parametri necessari.
42
+ */
43
+ buildCallbackUrl(authorizationCode: string): string;
44
+ /**
45
+ * Flusso completo: initiate -> poll -> redirect.
46
+ */
47
+ login(): Promise<void>;
48
+ on(event: ZoneOutEvent, callback: ZoneOutEventCallback): void;
49
+ off(event: ZoneOutEvent, callback: ZoneOutEventCallback): void;
50
+ private emit;
51
+ private mapServerError;
52
+ }
53
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EAEb,YAAY,EACZ,oBAAoB,EAErB,MAAM,SAAS,CAAC;AAGjB,OAAO,EAAmB,KAAK,aAAa,EAAE,MAAM,WAAW,CAAC;AAEhE,MAAM,WAAW,eAAe;IAC9B,6EAA6E;IAC7E,SAAS,EAAE,MAAM,CAAC;IAClB,iCAAiC;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,2BAA2B;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,6CAA6C;IAC7C,KAAK,EAAE,eAAe,CAAC;IACvB;;;;OAIG;IACH,eAAe,EAAE,MAAM,OAAO,CAAC,aAAa,CAAC,CAAC;CAC/C;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAA0B;IACxC,OAAO,CAAC,SAAS,CAA2D;IAC5E,OAAO,CAAC,aAAa,CAAuB;IAC5C,OAAO,CAAC,MAAM,CAAuB;gBAEzB,MAAM,EAAE,aAAa;IAUjC;;;OAGG;IACG,aAAa,IAAI,OAAO,CAAC,eAAe,CAAC;IAgE/C;;;;OAIG;IACH,eAAe,IAAI,MAAM,GAAG,IAAI;IAIhC;;OAEG;IACH,QAAQ,IAAI,MAAM,GAAG,IAAI;IAIzB;;OAEG;IACH,gBAAgB,CAAC,iBAAiB,EAAE,MAAM,GAAG,MAAM;IAOnD;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAW5B,EAAE,CAAC,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,oBAAoB,GAAG,IAAI;IAO7D,GAAG,CAAC,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,oBAAoB,GAAG,IAAI;IAI9D,OAAO,CAAC,IAAI;IAIZ,OAAO,CAAC,cAAc;CAQvB"}
@@ -0,0 +1,137 @@
1
+ import { ZoneOutError } from './errors';
2
+ import { generateCodeVerifier, generateCodeChallenge, generateState } from './pkce';
3
+ import { pollForApproval } from './polling';
4
+ export class ZoneOutClient {
5
+ constructor(config) {
6
+ this.listeners = new Map();
7
+ this._codeVerifier = null;
8
+ this._state = null;
9
+ this.config = {
10
+ ...config,
11
+ apiKey: config.apiKey ?? '',
12
+ scope: config.scope ?? ['identity'],
13
+ pollingTimeout: config.pollingTimeout ?? 300000,
14
+ pollingInterval: config.pollingInterval ?? 2000,
15
+ };
16
+ }
17
+ /**
18
+ * Avvia il flusso di login.
19
+ * Restituisce l'URL del QR code e una promise per attendere l'approvazione.
20
+ */
21
+ async initiateLogin() {
22
+ const codeVerifier = generateCodeVerifier();
23
+ const codeChallenge = await generateCodeChallenge(codeVerifier);
24
+ const state = generateState();
25
+ this._codeVerifier = codeVerifier;
26
+ this._state = state;
27
+ this.emit('login_start');
28
+ const res = await fetch(`${this.config.authServerUrl}/auth-login-initiate`, {
29
+ method: 'POST',
30
+ headers: {
31
+ 'Content-Type': 'application/json',
32
+ ...(this.config.apiKey ? { apikey: this.config.apiKey, Authorization: `Bearer ${this.config.apiKey}` } : {}),
33
+ },
34
+ body: JSON.stringify({
35
+ client_id: this.config.clientId,
36
+ code_challenge: codeChallenge,
37
+ code_challenge_method: 'S256',
38
+ redirect_uri: this.config.redirectUri,
39
+ state,
40
+ scope: this.config.scope.join(' '),
41
+ }),
42
+ });
43
+ if (!res.ok) {
44
+ const body = await res.json().catch(() => ({}));
45
+ const code = this.mapServerError(body);
46
+ throw new ZoneOutError(code, body.error || `Initiate failed: HTTP ${res.status}`, body);
47
+ }
48
+ const session = await res.json();
49
+ const abortController = new AbortController();
50
+ const qrCodeUrl = `zoneout://approve/${session.login_session_id}`;
51
+ const waitForApproval = async () => {
52
+ const result = await pollForApproval({
53
+ sessionId: session.login_session_id,
54
+ authServerUrl: this.config.authServerUrl,
55
+ apiKey: this.config.apiKey,
56
+ interval: this.config.pollingInterval,
57
+ timeout: this.config.pollingTimeout,
58
+ signal: abortController.signal,
59
+ onStatusChange: (status) => {
60
+ if (status === 'approved')
61
+ this.emit('login_approved');
62
+ if (status === 'rejected')
63
+ this.emit('login_rejected');
64
+ if (status === 'expired')
65
+ this.emit('login_expired');
66
+ },
67
+ });
68
+ return result;
69
+ };
70
+ return {
71
+ qrCodeUrl,
72
+ sessionId: session.login_session_id,
73
+ expiresAt: session.expires_at,
74
+ abort: abortController,
75
+ waitForApproval,
76
+ };
77
+ }
78
+ /**
79
+ * Restituisce il code_verifier generato nell'ultimo initiateLogin.
80
+ * Serve al backend per il token exchange.
81
+ * ATTENZIONE: NON inviare mai il code_verifier a terzi. Va solo al TUO backend.
82
+ */
83
+ getCodeVerifier() {
84
+ return this._codeVerifier;
85
+ }
86
+ /**
87
+ * Restituisce lo state generato nell'ultimo initiateLogin.
88
+ */
89
+ getState() {
90
+ return this._state;
91
+ }
92
+ /**
93
+ * Genera l'URL di redirect al backend del consumer con i parametri necessari.
94
+ */
95
+ buildCallbackUrl(authorizationCode) {
96
+ const url = new URL(this.config.redirectUri);
97
+ url.searchParams.set('code', authorizationCode);
98
+ url.searchParams.set('state', this._state ?? '');
99
+ return url.toString();
100
+ }
101
+ /**
102
+ * Flusso completo: initiate -> poll -> redirect.
103
+ */
104
+ async login() {
105
+ const { waitForApproval } = await this.initiateLogin();
106
+ const result = await waitForApproval();
107
+ if (result.authorization_code) {
108
+ window.location.href = this.buildCallbackUrl(result.authorization_code);
109
+ }
110
+ }
111
+ // --- Event system ---
112
+ on(event, callback) {
113
+ if (!this.listeners.has(event)) {
114
+ this.listeners.set(event, new Set());
115
+ }
116
+ this.listeners.get(event).add(callback);
117
+ }
118
+ off(event, callback) {
119
+ this.listeners.get(event)?.delete(callback);
120
+ }
121
+ emit(event, data) {
122
+ this.listeners.get(event)?.forEach(cb => cb(event, data));
123
+ }
124
+ mapServerError(body) {
125
+ const error = String(body.error || '');
126
+ if (error.includes('client') || error.includes('client_id'))
127
+ return 'INVALID_CLIENT';
128
+ if (error.includes('redirect'))
129
+ return 'INVALID_REDIRECT';
130
+ if (error.includes('rate') || error.includes('limit'))
131
+ return 'RATE_LIMITED';
132
+ if (error.includes('provider'))
133
+ return 'PROVIDER_MISSING';
134
+ return 'UNKNOWN_ERROR';
135
+ }
136
+ }
137
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { ZoneOutErrorCode } from './types';
2
+ export declare class ZoneOutError extends Error {
3
+ readonly code: ZoneOutErrorCode;
4
+ readonly detail?: Record<string, unknown>;
5
+ constructor(code: ZoneOutErrorCode, message: string, detail?: Record<string, unknown>);
6
+ }
7
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAEhD,qBAAa,YAAa,SAAQ,KAAK;IACrC,SAAgB,IAAI,EAAE,gBAAgB,CAAC;IACvC,SAAgB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;gBAErC,IAAI,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CAMtF"}
@@ -0,0 +1,9 @@
1
+ export class ZoneOutError extends Error {
2
+ constructor(code, message, detail) {
3
+ super(message);
4
+ this.name = 'ZoneOutError';
5
+ this.code = code;
6
+ this.detail = detail;
7
+ }
8
+ }
9
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,YAAa,SAAQ,KAAK;IAIrC,YAAY,IAAsB,EAAE,OAAe,EAAE,MAAgC;QACnF,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC;QAC3B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;CACF"}
@@ -0,0 +1,7 @@
1
+ export { ZoneOutClient } from './client';
2
+ export type { LoginInitResult } from './client';
3
+ export { exchangeCodeForTokens, refreshAccessToken } from './server';
4
+ export type { ZoneOutConfig, ZoneOutUser, ZoneOutTokens, ZoneOutLoginResult, LoginSession, LoginSessionStatus, LoginSessionDetail, LoginSessionResponse, TokenExchangeParams, TokenRefreshParams, TokenResponse, ZoneOutEvent, ZoneOutEventCallback, ZoneOutErrorCode, } from './types';
5
+ export { ZoneOutError } from './errors';
6
+ export { generateCodeVerifier, generateCodeChallenge, generateState } from './pkce';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,YAAY,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAGhD,OAAO,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAGrE,YAAY,EACV,aAAa,EACb,WAAW,EACX,aAAa,EACb,kBAAkB,EAClB,YAAY,EACZ,kBAAkB,EAClB,kBAAkB,EAClB,oBAAoB,EACpB,mBAAmB,EACnB,kBAAkB,EAClB,aAAa,EACb,YAAY,EACZ,oBAAoB,EACpB,gBAAgB,GACjB,MAAM,SAAS,CAAC;AAGjB,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAGxC,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC"}
@@ -0,0 +1,9 @@
1
+ // Client (frontend)
2
+ export { ZoneOutClient } from './client';
3
+ // Server helpers
4
+ export { exchangeCodeForTokens, refreshAccessToken } from './server';
5
+ // Errors
6
+ export { ZoneOutError } from './errors';
7
+ // PKCE utils (exported for advanced use cases)
8
+ export { generateCodeVerifier, generateCodeChallenge, generateState } from './pkce';
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,oBAAoB;AACpB,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAGzC,iBAAiB;AACjB,OAAO,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAoBrE,SAAS;AACT,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAExC,+CAA+C;AAC/C,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC"}
@@ -0,0 +1,4 @@
1
+ export declare function generateCodeVerifier(): string;
2
+ export declare function generateCodeChallenge(verifier: string): Promise<string>;
3
+ export declare function generateState(): string;
4
+ //# sourceMappingURL=pkce.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pkce.d.ts","sourceRoot":"","sources":["../../src/pkce.ts"],"names":[],"mappings":"AASA,wBAAgB,oBAAoB,IAAI,MAAM,CAI7C;AAED,wBAAsB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAK7E;AAED,wBAAgB,aAAa,IAAI,MAAM,CAItC"}
@@ -0,0 +1,25 @@
1
+ function base64UrlEncode(buffer) {
2
+ const bytes = new Uint8Array(buffer);
3
+ let binary = '';
4
+ for (let i = 0; i < bytes.length; i++) {
5
+ binary += String.fromCharCode(bytes[i]);
6
+ }
7
+ return btoa(binary).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
8
+ }
9
+ export function generateCodeVerifier() {
10
+ const array = new Uint8Array(48);
11
+ crypto.getRandomValues(array);
12
+ return base64UrlEncode(array.buffer);
13
+ }
14
+ export async function generateCodeChallenge(verifier) {
15
+ const encoder = new TextEncoder();
16
+ const data = encoder.encode(verifier);
17
+ const hash = await crypto.subtle.digest('SHA-256', data);
18
+ return base64UrlEncode(hash);
19
+ }
20
+ export function generateState() {
21
+ const array = new Uint8Array(32);
22
+ crypto.getRandomValues(array);
23
+ return base64UrlEncode(array.buffer);
24
+ }
25
+ //# sourceMappingURL=pkce.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pkce.js","sourceRoot":"","sources":["../../src/pkce.ts"],"names":[],"mappings":"AAAA,SAAS,eAAe,CAAC,MAAmB;IAC1C,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC;IACrC,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,IAAI,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1C,CAAC;IACD,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;AACjF,CAAC;AAED,MAAM,UAAU,oBAAoB;IAClC,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC;IACjC,MAAM,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;IAC9B,OAAO,eAAe,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;AACvC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,QAAgB;IAC1D,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;IAClC,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IACtC,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IACzD,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC;AAC/B,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC;IACjC,MAAM,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;IAC9B,OAAO,eAAe,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;AACvC,CAAC"}
@@ -0,0 +1,15 @@
1
+ export interface PollingOptions {
2
+ sessionId: string;
3
+ authServerUrl: string;
4
+ apiKey?: string;
5
+ interval: number;
6
+ timeout: number;
7
+ onStatusChange?: (status: string) => void;
8
+ signal?: AbortSignal;
9
+ }
10
+ export interface PollingResult {
11
+ status: string;
12
+ authorization_code?: string;
13
+ }
14
+ export declare function pollForApproval(options: PollingOptions): Promise<PollingResult>;
15
+ //# sourceMappingURL=polling.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"polling.d.ts","sourceRoot":"","sources":["../../src/polling.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,wBAAsB,eAAe,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC,CAwDrF"}
@@ -0,0 +1,50 @@
1
+ import { ZoneOutError } from './errors';
2
+ export async function pollForApproval(options) {
3
+ const { sessionId, authServerUrl, apiKey, interval, timeout, onStatusChange, signal } = options;
4
+ const startTime = Date.now();
5
+ while (true) {
6
+ if (signal?.aborted) {
7
+ throw new ZoneOutError('USER_REJECTED', 'Login cancelled by user');
8
+ }
9
+ if (Date.now() - startTime > timeout) {
10
+ throw new ZoneOutError('POLLING_TIMEOUT', 'Login session timed out');
11
+ }
12
+ try {
13
+ const url = `${authServerUrl}/auth-login-session?session_id=${encodeURIComponent(sessionId)}`;
14
+ const res = await fetch(url, {
15
+ headers: {
16
+ ...(apiKey ? { apikey: apiKey, Authorization: `Bearer ${apiKey}` } : {}),
17
+ },
18
+ });
19
+ if (res.status === 429) {
20
+ throw new ZoneOutError('RATE_LIMITED', 'Too many requests, slow down');
21
+ }
22
+ if (!res.ok) {
23
+ const body = await res.json().catch(() => ({}));
24
+ throw new ZoneOutError('UNKNOWN_ERROR', body.error || `HTTP ${res.status}`);
25
+ }
26
+ const data = await res.json();
27
+ const status = data.session.status;
28
+ if (status === 'approved' && data.authorization_code) {
29
+ onStatusChange?.('approved');
30
+ return { status: 'approved', authorization_code: data.authorization_code };
31
+ }
32
+ if (status === 'rejected') {
33
+ onStatusChange?.('rejected');
34
+ throw new ZoneOutError('USER_REJECTED', 'User rejected the login request');
35
+ }
36
+ if (status === 'expired') {
37
+ onStatusChange?.('expired');
38
+ throw new ZoneOutError('SESSION_EXPIRED', 'Login session has expired');
39
+ }
40
+ onStatusChange?.('pending_approval');
41
+ }
42
+ catch (err) {
43
+ if (err instanceof ZoneOutError)
44
+ throw err;
45
+ console.warn('[ZoneOut SDK] Polling error, retrying:', err);
46
+ }
47
+ await new Promise(resolve => setTimeout(resolve, interval));
48
+ }
49
+ }
50
+ //# sourceMappingURL=polling.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"polling.js","sourceRoot":"","sources":["../../src/polling.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAiBxC,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,OAAuB;IAC3D,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IAChG,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAE7B,OAAO,IAAI,EAAE,CAAC;QACZ,IAAI,MAAM,EAAE,OAAO,EAAE,CAAC;YACpB,MAAM,IAAI,YAAY,CAAC,eAAe,EAAE,yBAAyB,CAAC,CAAC;QACrE,CAAC;QAED,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,GAAG,OAAO,EAAE,CAAC;YACrC,MAAM,IAAI,YAAY,CAAC,iBAAiB,EAAE,yBAAyB,CAAC,CAAC;QACvE,CAAC;QAED,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,GAAG,aAAa,kCAAkC,kBAAkB,CAAC,SAAS,CAAC,EAAE,CAAC;YAC9F,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;gBAC3B,OAAO,EAAE;oBACP,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,UAAU,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;iBACzE;aACF,CAAC,CAAC;YAEH,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;gBACvB,MAAM,IAAI,YAAY,CAAC,cAAc,EAAE,8BAA8B,CAAC,CAAC;YACzE,CAAC;YAED,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;gBACZ,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;gBAChD,MAAM,IAAI,YAAY,CAAC,eAAe,EAAE,IAAI,CAAC,KAAK,IAAI,QAAQ,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;YAC9E,CAAC;YAED,MAAM,IAAI,GAAyB,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;YACpD,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;YAEnC,IAAI,MAAM,KAAK,UAAU,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;gBACrD,cAAc,EAAE,CAAC,UAAU,CAAC,CAAC;gBAC7B,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,kBAAkB,EAAE,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC7E,CAAC;YAED,IAAI,MAAM,KAAK,UAAU,EAAE,CAAC;gBAC1B,cAAc,EAAE,CAAC,UAAU,CAAC,CAAC;gBAC7B,MAAM,IAAI,YAAY,CAAC,eAAe,EAAE,iCAAiC,CAAC,CAAC;YAC7E,CAAC;YAED,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;gBACzB,cAAc,EAAE,CAAC,SAAS,CAAC,CAAC;gBAC5B,MAAM,IAAI,YAAY,CAAC,iBAAiB,EAAE,2BAA2B,CAAC,CAAC;YACzE,CAAC;YAED,cAAc,EAAE,CAAC,kBAAkB,CAAC,CAAC;QACvC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,GAAG,YAAY,YAAY;gBAAE,MAAM,GAAG,CAAC;YAC3C,OAAO,CAAC,IAAI,CAAC,wCAAwC,EAAE,GAAG,CAAC,CAAC;QAC9D,CAAC;QAED,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC;IAC9D,CAAC;AACH,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { ZoneOutProvider, useZoneOutClient } from './provider';
2
+ export { useZoneOut } from './use-zoneout';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/react/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC/D,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC"}