@bigso/auth-sdk 0.4.5 → 0.4.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{index.cjs → browser/index.cjs} +5 -5
- package/dist/{index.d.cts → browser/index.d.cts} +3 -20
- package/dist/{index.d.ts → browser/index.d.ts} +3 -20
- package/dist/{index.js → browser/index.js} +5 -11
- package/dist/chunk-LDDK6SJD.js +13 -0
- package/dist/express/index.cjs +287 -0
- package/dist/express/index.d.cts +48 -0
- package/dist/express/index.d.ts +48 -0
- package/dist/express/index.js +257 -0
- package/dist/node/index.cjs +170 -0
- package/dist/node/index.d.cts +45 -0
- package/dist/node/index.d.ts +45 -0
- package/dist/node/index.js +137 -0
- package/dist/types-CoXgtTry.d.cts +51 -0
- package/dist/types-CoXgtTry.d.ts +51 -0
- package/package.json +34 -6
|
@@ -17,12 +17,12 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
17
17
|
};
|
|
18
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
19
|
|
|
20
|
-
// src/index.ts
|
|
21
|
-
var
|
|
22
|
-
__export(
|
|
20
|
+
// src/browser/index.ts
|
|
21
|
+
var browser_exports = {};
|
|
22
|
+
__export(browser_exports, {
|
|
23
23
|
BigsoAuth: () => BigsoAuth
|
|
24
24
|
});
|
|
25
|
-
module.exports = __toCommonJS(
|
|
25
|
+
module.exports = __toCommonJS(browser_exports);
|
|
26
26
|
|
|
27
27
|
// src/utils/crypto.ts
|
|
28
28
|
async function sha256Base64Url(input) {
|
|
@@ -71,7 +71,7 @@ async function verifySignedPayload(token, jwksUrl, expectedAudience) {
|
|
|
71
71
|
return payload;
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
// src/
|
|
74
|
+
// src/browser/auth.ts
|
|
75
75
|
var BigsoAuth = class extends EventEmitter {
|
|
76
76
|
constructor(options) {
|
|
77
77
|
super();
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { B as BigsoAuthOptions } from '../types-CoXgtTry.cjs';
|
|
2
|
+
|
|
1
3
|
declare class EventEmitter {
|
|
2
4
|
private events;
|
|
3
5
|
on(event: string, handler: Function): void;
|
|
@@ -5,25 +7,6 @@ declare class EventEmitter {
|
|
|
5
7
|
emit(event: string, data?: any): void;
|
|
6
8
|
}
|
|
7
9
|
|
|
8
|
-
interface BigsoAuthOptions {
|
|
9
|
-
/** Client ID registrado en el SSO */
|
|
10
|
-
clientId: string;
|
|
11
|
-
/** Origen del SSO (ej: https://sso.bigso.co) */
|
|
12
|
-
ssoOrigin: string;
|
|
13
|
-
/** URL del JWKS para verificar firmas (ej: https://sso.bigso.co/.well-known/jwks.json) */
|
|
14
|
-
jwksUrl: string;
|
|
15
|
-
/** Timeout en milisegundos (por defecto 5000) */
|
|
16
|
-
timeout?: number;
|
|
17
|
-
/** Activar logs de depuración */
|
|
18
|
-
debug?: boolean;
|
|
19
|
-
/** URI de redirección registrada (opcional, si se requiere validación exacta) */
|
|
20
|
-
redirectUri?: string;
|
|
21
|
-
/** Sugerencia de tenant (opcional) */
|
|
22
|
-
tenantHint?: string;
|
|
23
|
-
/** Tema visual del iframe ('light' | 'dark', por defecto 'light') */
|
|
24
|
-
theme?: 'light' | 'dark';
|
|
25
|
-
}
|
|
26
|
-
|
|
27
10
|
declare class BigsoAuth extends EventEmitter {
|
|
28
11
|
private options;
|
|
29
12
|
private iframe?;
|
|
@@ -63,4 +46,4 @@ declare class BigsoAuth extends EventEmitter {
|
|
|
63
46
|
private debug;
|
|
64
47
|
}
|
|
65
48
|
|
|
66
|
-
export { BigsoAuth,
|
|
49
|
+
export { BigsoAuth, BigsoAuthOptions };
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { B as BigsoAuthOptions } from '../types-CoXgtTry.js';
|
|
2
|
+
|
|
1
3
|
declare class EventEmitter {
|
|
2
4
|
private events;
|
|
3
5
|
on(event: string, handler: Function): void;
|
|
@@ -5,25 +7,6 @@ declare class EventEmitter {
|
|
|
5
7
|
emit(event: string, data?: any): void;
|
|
6
8
|
}
|
|
7
9
|
|
|
8
|
-
interface BigsoAuthOptions {
|
|
9
|
-
/** Client ID registrado en el SSO */
|
|
10
|
-
clientId: string;
|
|
11
|
-
/** Origen del SSO (ej: https://sso.bigso.co) */
|
|
12
|
-
ssoOrigin: string;
|
|
13
|
-
/** URL del JWKS para verificar firmas (ej: https://sso.bigso.co/.well-known/jwks.json) */
|
|
14
|
-
jwksUrl: string;
|
|
15
|
-
/** Timeout en milisegundos (por defecto 5000) */
|
|
16
|
-
timeout?: number;
|
|
17
|
-
/** Activar logs de depuración */
|
|
18
|
-
debug?: boolean;
|
|
19
|
-
/** URI de redirección registrada (opcional, si se requiere validación exacta) */
|
|
20
|
-
redirectUri?: string;
|
|
21
|
-
/** Sugerencia de tenant (opcional) */
|
|
22
|
-
tenantHint?: string;
|
|
23
|
-
/** Tema visual del iframe ('light' | 'dark', por defecto 'light') */
|
|
24
|
-
theme?: 'light' | 'dark';
|
|
25
|
-
}
|
|
26
|
-
|
|
27
10
|
declare class BigsoAuth extends EventEmitter {
|
|
28
11
|
private options;
|
|
29
12
|
private iframe?;
|
|
@@ -63,4 +46,4 @@ declare class BigsoAuth extends EventEmitter {
|
|
|
63
46
|
private debug;
|
|
64
47
|
}
|
|
65
48
|
|
|
66
|
-
export { BigsoAuth,
|
|
49
|
+
export { BigsoAuth, BigsoAuthOptions };
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import {
|
|
2
|
+
verifySignedPayload
|
|
3
|
+
} from "../chunk-LDDK6SJD.js";
|
|
4
|
+
|
|
1
5
|
// src/utils/crypto.ts
|
|
2
6
|
async function sha256Base64Url(input) {
|
|
3
7
|
const encoder = new TextEncoder();
|
|
@@ -35,17 +39,7 @@ var EventEmitter = class {
|
|
|
35
39
|
}
|
|
36
40
|
};
|
|
37
41
|
|
|
38
|
-
// src/
|
|
39
|
-
import { jwtVerify, createRemoteJWKSet } from "jose";
|
|
40
|
-
async function verifySignedPayload(token, jwksUrl, expectedAudience) {
|
|
41
|
-
const JWKS = createRemoteJWKSet(new URL(jwksUrl));
|
|
42
|
-
const { payload } = await jwtVerify(token, JWKS, {
|
|
43
|
-
audience: expectedAudience
|
|
44
|
-
});
|
|
45
|
-
return payload;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
// src/core/auth.ts
|
|
42
|
+
// src/browser/auth.ts
|
|
49
43
|
var BigsoAuth = class extends EventEmitter {
|
|
50
44
|
constructor(options) {
|
|
51
45
|
super();
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// src/utils/jws.ts
|
|
2
|
+
import { jwtVerify, createRemoteJWKSet } from "jose";
|
|
3
|
+
async function verifySignedPayload(token, jwksUrl, expectedAudience) {
|
|
4
|
+
const JWKS = createRemoteJWKSet(new URL(jwksUrl));
|
|
5
|
+
const { payload } = await jwtVerify(token, JWKS, {
|
|
6
|
+
audience: expectedAudience
|
|
7
|
+
});
|
|
8
|
+
return payload;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export {
|
|
12
|
+
verifySignedPayload
|
|
13
|
+
};
|
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/express/index.ts
|
|
21
|
+
var express_exports = {};
|
|
22
|
+
__export(express_exports, {
|
|
23
|
+
createSsoAuthRouter: () => createSsoAuthRouter,
|
|
24
|
+
createSsoSyncRouter: () => createSsoSyncRouter,
|
|
25
|
+
ssoAuthMiddleware: () => ssoAuthMiddleware,
|
|
26
|
+
ssoSyncGuardMiddleware: () => ssoSyncGuardMiddleware
|
|
27
|
+
});
|
|
28
|
+
module.exports = __toCommonJS(express_exports);
|
|
29
|
+
|
|
30
|
+
// src/express/middlewares/ssoAuth.ts
|
|
31
|
+
function ssoAuthMiddleware(options) {
|
|
32
|
+
const cookieName = options.cookieName || "sso_session";
|
|
33
|
+
const isProduction = options.isProduction ?? process.env.NODE_ENV === "production";
|
|
34
|
+
return async (req, res, next) => {
|
|
35
|
+
try {
|
|
36
|
+
let sessionToken = req.cookies?.[cookieName];
|
|
37
|
+
let session = null;
|
|
38
|
+
if (sessionToken) {
|
|
39
|
+
session = await options.ssoClient.validateSessionToken(sessionToken);
|
|
40
|
+
}
|
|
41
|
+
if (!session) {
|
|
42
|
+
const refreshToken = req.cookies?.[`${cookieName}_refresh`];
|
|
43
|
+
if (refreshToken) {
|
|
44
|
+
const newSessionData = await options.ssoClient.refreshAppSession(refreshToken);
|
|
45
|
+
if (newSessionData) {
|
|
46
|
+
const sessionMaxAge = new Date(newSessionData.expiresAt).getTime() - Date.now();
|
|
47
|
+
const refreshMaxAge = newSessionData.refreshExpiresAt ? new Date(newSessionData.refreshExpiresAt).getTime() - Date.now() : 7 * 24 * 60 * 60 * 1e3;
|
|
48
|
+
const sessionCookieOptions = {
|
|
49
|
+
httpOnly: true,
|
|
50
|
+
secure: isProduction,
|
|
51
|
+
sameSite: "lax",
|
|
52
|
+
path: "/",
|
|
53
|
+
maxAge: sessionMaxAge > 0 ? sessionMaxAge : 0,
|
|
54
|
+
...isProduction && options.cookieDomain ? { domain: options.cookieDomain } : {}
|
|
55
|
+
};
|
|
56
|
+
const refreshCookieOptions = {
|
|
57
|
+
...sessionCookieOptions,
|
|
58
|
+
maxAge: refreshMaxAge > 0 ? refreshMaxAge : 0
|
|
59
|
+
};
|
|
60
|
+
res.cookie(cookieName, newSessionData.sessionToken, sessionCookieOptions);
|
|
61
|
+
res.cookie(`${cookieName}_refresh`, newSessionData.refreshToken, refreshCookieOptions);
|
|
62
|
+
session = await options.ssoClient.validateSessionToken(newSessionData.sessionToken);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
if (!session) {
|
|
66
|
+
res.clearCookie(cookieName);
|
|
67
|
+
res.clearCookie(`${cookieName}_refresh`);
|
|
68
|
+
res.status(401).json({ error: "Session expired or invalid" });
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
if (options.onSessionValidated) {
|
|
73
|
+
await options.onSessionValidated(session, req);
|
|
74
|
+
}
|
|
75
|
+
req.user = session.user;
|
|
76
|
+
req.tenant = session.tenant;
|
|
77
|
+
req.ssoSession = session;
|
|
78
|
+
next();
|
|
79
|
+
} catch (error) {
|
|
80
|
+
console.error("\u274C [BigsoAuthSDK] Authentication Middleware Error:", error instanceof Error ? error.message : error);
|
|
81
|
+
res.status(500).json({ error: "Internal authentication error" });
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// src/express/middlewares/ssoSyncGuard.ts
|
|
87
|
+
var import_dns = require("dns");
|
|
88
|
+
function ssoSyncGuardMiddleware(options) {
|
|
89
|
+
const isProduction = options.isProduction ?? process.env.NODE_ENV === "production";
|
|
90
|
+
return async (req, res, next) => {
|
|
91
|
+
try {
|
|
92
|
+
const isSecure = req.secure || req.headers["x-forwarded-proto"] === "https";
|
|
93
|
+
if (!isSecure && isProduction) {
|
|
94
|
+
console.warn("\u26A0\uFE0F [BigsoAuthSDK] Blocked non-HTTPS sync request");
|
|
95
|
+
res.status(403).json({ error: "HTTPS required" });
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
const clientIp = req.ip || req.socket.remoteAddress || "";
|
|
99
|
+
const isLoopback = clientIp === "::1" || clientIp === "127.0.0.1" || clientIp === "::ffff:127.0.0.1";
|
|
100
|
+
if (!isProduction && isLoopback) {
|
|
101
|
+
return next();
|
|
102
|
+
}
|
|
103
|
+
const ssoUrl = new URL(options.ssoBackendUrl);
|
|
104
|
+
const ssoHostname = ssoUrl.hostname;
|
|
105
|
+
const ssoIps = await import_dns.promises.resolve4(ssoHostname).catch(() => []);
|
|
106
|
+
const cleanClientIp = clientIp.replace(/^.*:/, "");
|
|
107
|
+
const isPrivateIp = cleanClientIp.startsWith("10.") || cleanClientIp.startsWith("192.168.") || cleanClientIp.startsWith("172.") && parseInt(cleanClientIp.split(".")[1], 10) >= 16 && parseInt(cleanClientIp.split(".")[1], 10) <= 31;
|
|
108
|
+
if (!ssoIps.includes(cleanClientIp) && !isPrivateIp) {
|
|
109
|
+
console.warn(`\u26D4\uFE0F [BigsoAuthSDK] Blocked sync request from unauthorized IP: ${clientIp}`);
|
|
110
|
+
res.status(403).json({ error: "Unauthorized origin" });
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
next();
|
|
114
|
+
} catch (error) {
|
|
115
|
+
console.error("\u274C [BigsoAuthSDK] Sync Guard Validation Error:", error instanceof Error ? error.message : error);
|
|
116
|
+
res.status(500).json({ error: "Security validation failed" });
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// src/express/routes/createSsoAuthRouter.ts
|
|
122
|
+
var import_express = require("express");
|
|
123
|
+
function createSsoAuthRouter(options) {
|
|
124
|
+
const router = (0, import_express.Router)();
|
|
125
|
+
const cookieName = options.cookieName || "sso_session";
|
|
126
|
+
const isProduction = options.isProduction ?? process.env.NODE_ENV === "production";
|
|
127
|
+
const getCookieOptions = (customOptions = {}) => {
|
|
128
|
+
const base = {
|
|
129
|
+
httpOnly: true,
|
|
130
|
+
secure: isProduction,
|
|
131
|
+
sameSite: "lax",
|
|
132
|
+
path: "/",
|
|
133
|
+
...customOptions
|
|
134
|
+
};
|
|
135
|
+
if (isProduction && options.cookieDomain) {
|
|
136
|
+
base.domain = options.cookieDomain;
|
|
137
|
+
}
|
|
138
|
+
return base;
|
|
139
|
+
};
|
|
140
|
+
router.post("/exchange", async (req, res) => {
|
|
141
|
+
try {
|
|
142
|
+
const { code } = req.body;
|
|
143
|
+
if (!code) {
|
|
144
|
+
res.status(400).json({ error: "Authorization code is required" });
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
const ssoResponse = await options.ssoClient.exchangeCodeForToken(code);
|
|
148
|
+
if (!ssoResponse.success) {
|
|
149
|
+
res.status(401).json({ error: "Invalid authorization code" });
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
const sessionMaxAge = new Date(ssoResponse.expiresAt).getTime() - Date.now();
|
|
153
|
+
const refreshMaxAge = ssoResponse.refreshExpiresAt ? new Date(ssoResponse.refreshExpiresAt).getTime() - Date.now() : 7 * 24 * 60 * 60 * 1e3;
|
|
154
|
+
const sessionCookieOptions = getCookieOptions({
|
|
155
|
+
maxAge: sessionMaxAge > 0 ? sessionMaxAge : 0
|
|
156
|
+
});
|
|
157
|
+
const refreshCookieOptions = getCookieOptions({
|
|
158
|
+
maxAge: refreshMaxAge > 0 ? refreshMaxAge : 0
|
|
159
|
+
});
|
|
160
|
+
res.cookie(cookieName, ssoResponse.sessionToken, sessionCookieOptions);
|
|
161
|
+
if (ssoResponse.refreshToken) {
|
|
162
|
+
res.cookie(`${cookieName}_refresh`, ssoResponse.refreshToken, refreshCookieOptions);
|
|
163
|
+
}
|
|
164
|
+
if (options.onLoginSuccess) {
|
|
165
|
+
await options.onLoginSuccess(ssoResponse);
|
|
166
|
+
}
|
|
167
|
+
res.json({
|
|
168
|
+
success: true,
|
|
169
|
+
user: ssoResponse.user,
|
|
170
|
+
tenant: ssoResponse.tenant,
|
|
171
|
+
expiresAt: ssoResponse.expiresAt
|
|
172
|
+
});
|
|
173
|
+
} catch (error) {
|
|
174
|
+
console.error("\u274C [BigsoAuthSDK] Error exchanging code:", error.message);
|
|
175
|
+
res.status(500).json({
|
|
176
|
+
error: error.message || "Failed to exchange authorization code"
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
});
|
|
180
|
+
router.post("/exchange-v2", async (req, res) => {
|
|
181
|
+
try {
|
|
182
|
+
const { payload } = req.body;
|
|
183
|
+
if (!payload) {
|
|
184
|
+
res.status(400).json({ error: "Signed payload is required" });
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
const verified = await options.ssoClient.verifySignedPayload(payload, options.frontendUrl);
|
|
188
|
+
if (!verified.code) {
|
|
189
|
+
res.status(400).json({ error: "No authorization code found in payload" });
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
const ssoResponse = await options.ssoClient.exchangeCodeForToken(verified.code);
|
|
193
|
+
if (!ssoResponse.success) {
|
|
194
|
+
res.status(401).json({ error: "Invalid authorization code" });
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
const sessionMaxAge = new Date(ssoResponse.expiresAt).getTime() - Date.now();
|
|
198
|
+
const refreshMaxAge = ssoResponse.refreshExpiresAt ? new Date(ssoResponse.refreshExpiresAt).getTime() - Date.now() : 7 * 24 * 60 * 60 * 1e3;
|
|
199
|
+
const sessionCookieOptions = getCookieOptions({
|
|
200
|
+
maxAge: sessionMaxAge > 0 ? sessionMaxAge : 0
|
|
201
|
+
});
|
|
202
|
+
const refreshCookieOptions = getCookieOptions({
|
|
203
|
+
maxAge: refreshMaxAge > 0 ? refreshMaxAge : 0
|
|
204
|
+
});
|
|
205
|
+
res.cookie(cookieName, ssoResponse.sessionToken, sessionCookieOptions);
|
|
206
|
+
if (ssoResponse.refreshToken) {
|
|
207
|
+
res.cookie(`${cookieName}_refresh`, ssoResponse.refreshToken, refreshCookieOptions);
|
|
208
|
+
}
|
|
209
|
+
if (options.onLoginSuccess) {
|
|
210
|
+
await options.onLoginSuccess(ssoResponse);
|
|
211
|
+
}
|
|
212
|
+
res.json({
|
|
213
|
+
success: true,
|
|
214
|
+
user: ssoResponse.user,
|
|
215
|
+
tenant: ssoResponse.tenant,
|
|
216
|
+
expiresAt: ssoResponse.expiresAt
|
|
217
|
+
});
|
|
218
|
+
} catch (error) {
|
|
219
|
+
console.error("\u274C [BigsoAuthSDK] Error exchanging v2 payload:", error.message);
|
|
220
|
+
res.status(401).json({
|
|
221
|
+
error: error.message || "Failed to verify signed payload"
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
});
|
|
225
|
+
router.get("/session", ssoAuthMiddleware(options), (req, res) => {
|
|
226
|
+
res.set("Cache-Control", "no-store, no-cache, must-revalidate, private");
|
|
227
|
+
res.set("Pragma", "no-cache");
|
|
228
|
+
res.set("Expires", "0");
|
|
229
|
+
res.json({
|
|
230
|
+
success: true,
|
|
231
|
+
user: req.user,
|
|
232
|
+
tenant: req.tenant,
|
|
233
|
+
expiresAt: req.ssoSession?.expiresAt
|
|
234
|
+
});
|
|
235
|
+
});
|
|
236
|
+
router.post("/logout", async (req, res) => {
|
|
237
|
+
const sessionToken = req.cookies?.[cookieName];
|
|
238
|
+
if (sessionToken) {
|
|
239
|
+
try {
|
|
240
|
+
await options.ssoClient.revokeSession(sessionToken);
|
|
241
|
+
} catch (error) {
|
|
242
|
+
console.warn("\u26A0\uFE0F [BigsoAuthSDK] Failed to revoke session in SSO Backend. Clearing local anyway.", error.message);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
const cookieOptions = getCookieOptions({ maxAge: 0 });
|
|
246
|
+
res.clearCookie(cookieName, cookieOptions);
|
|
247
|
+
res.clearCookie(`${cookieName}_refresh`, cookieOptions);
|
|
248
|
+
if (options.onLogout && sessionToken) {
|
|
249
|
+
await options.onLogout(sessionToken);
|
|
250
|
+
}
|
|
251
|
+
res.json({ success: true, message: "Logged out" });
|
|
252
|
+
});
|
|
253
|
+
return router;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// src/express/routes/createSsoSyncRouter.ts
|
|
257
|
+
var import_express2 = require("express");
|
|
258
|
+
function createSsoSyncRouter(options) {
|
|
259
|
+
const router = (0, import_express2.Router)();
|
|
260
|
+
router.get("/resources", ssoSyncGuardMiddleware({
|
|
261
|
+
ssoBackendUrl: options.ssoBackendUrl,
|
|
262
|
+
isProduction: options.isProduction
|
|
263
|
+
}), (req, res) => {
|
|
264
|
+
try {
|
|
265
|
+
res.json({
|
|
266
|
+
success: true,
|
|
267
|
+
resources: options.resources,
|
|
268
|
+
meta: {
|
|
269
|
+
appId: options.appId,
|
|
270
|
+
count: options.resources.length,
|
|
271
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
272
|
+
}
|
|
273
|
+
});
|
|
274
|
+
} catch (error) {
|
|
275
|
+
console.error("\u274C [BigsoAuthSDK] Error in sync endpoint:", error.message);
|
|
276
|
+
res.status(500).json({ error: error.message });
|
|
277
|
+
}
|
|
278
|
+
});
|
|
279
|
+
return router;
|
|
280
|
+
}
|
|
281
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
282
|
+
0 && (module.exports = {
|
|
283
|
+
createSsoAuthRouter,
|
|
284
|
+
createSsoSyncRouter,
|
|
285
|
+
ssoAuthMiddleware,
|
|
286
|
+
ssoSyncGuardMiddleware
|
|
287
|
+
});
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { Request, Response, NextFunction, Router } from 'express';
|
|
2
|
+
import { BigsoSsoClient } from '../node/index.cjs';
|
|
3
|
+
import { S as SsoSessionData } from '../types-CoXgtTry.cjs';
|
|
4
|
+
|
|
5
|
+
interface SsoAuthMiddlewareOptions {
|
|
6
|
+
ssoClient: BigsoSsoClient;
|
|
7
|
+
cookieName?: string;
|
|
8
|
+
cookieDomain?: string;
|
|
9
|
+
isProduction?: boolean;
|
|
10
|
+
onSessionValidated?: (session: SsoSessionData, req: Request) => Promise<void> | void;
|
|
11
|
+
}
|
|
12
|
+
declare global {
|
|
13
|
+
namespace Express {
|
|
14
|
+
interface Request {
|
|
15
|
+
user?: SsoSessionData['user'];
|
|
16
|
+
tenant?: SsoSessionData['tenant'];
|
|
17
|
+
ssoSession?: SsoSessionData;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
declare function ssoAuthMiddleware(options: SsoAuthMiddlewareOptions): (req: Request, res: Response, next: NextFunction) => Promise<void>;
|
|
22
|
+
|
|
23
|
+
interface SsoSyncGuardOptions {
|
|
24
|
+
ssoBackendUrl: string;
|
|
25
|
+
isProduction?: boolean;
|
|
26
|
+
}
|
|
27
|
+
declare function ssoSyncGuardMiddleware(options: SsoSyncGuardOptions): (req: Request, res: Response, next: NextFunction) => Promise<void>;
|
|
28
|
+
|
|
29
|
+
interface CreateSsoAuthRouterOptions {
|
|
30
|
+
ssoClient: BigsoSsoClient;
|
|
31
|
+
frontendUrl: string;
|
|
32
|
+
cookieName?: string;
|
|
33
|
+
cookieDomain?: string;
|
|
34
|
+
isProduction?: boolean;
|
|
35
|
+
onLoginSuccess?: (session: SsoSessionData) => void | Promise<void>;
|
|
36
|
+
onLogout?: (sessionToken: string) => void | Promise<void>;
|
|
37
|
+
}
|
|
38
|
+
declare function createSsoAuthRouter(options: CreateSsoAuthRouterOptions): Router;
|
|
39
|
+
|
|
40
|
+
interface SsoSyncRouterOptions {
|
|
41
|
+
resources: any[];
|
|
42
|
+
appId: string;
|
|
43
|
+
ssoBackendUrl: string;
|
|
44
|
+
isProduction?: boolean;
|
|
45
|
+
}
|
|
46
|
+
declare function createSsoSyncRouter(options: SsoSyncRouterOptions): Router;
|
|
47
|
+
|
|
48
|
+
export { type CreateSsoAuthRouterOptions, type SsoAuthMiddlewareOptions, type SsoSyncGuardOptions, type SsoSyncRouterOptions, createSsoAuthRouter, createSsoSyncRouter, ssoAuthMiddleware, ssoSyncGuardMiddleware };
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { Request, Response, NextFunction, Router } from 'express';
|
|
2
|
+
import { BigsoSsoClient } from '../node/index.js';
|
|
3
|
+
import { S as SsoSessionData } from '../types-CoXgtTry.js';
|
|
4
|
+
|
|
5
|
+
interface SsoAuthMiddlewareOptions {
|
|
6
|
+
ssoClient: BigsoSsoClient;
|
|
7
|
+
cookieName?: string;
|
|
8
|
+
cookieDomain?: string;
|
|
9
|
+
isProduction?: boolean;
|
|
10
|
+
onSessionValidated?: (session: SsoSessionData, req: Request) => Promise<void> | void;
|
|
11
|
+
}
|
|
12
|
+
declare global {
|
|
13
|
+
namespace Express {
|
|
14
|
+
interface Request {
|
|
15
|
+
user?: SsoSessionData['user'];
|
|
16
|
+
tenant?: SsoSessionData['tenant'];
|
|
17
|
+
ssoSession?: SsoSessionData;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
declare function ssoAuthMiddleware(options: SsoAuthMiddlewareOptions): (req: Request, res: Response, next: NextFunction) => Promise<void>;
|
|
22
|
+
|
|
23
|
+
interface SsoSyncGuardOptions {
|
|
24
|
+
ssoBackendUrl: string;
|
|
25
|
+
isProduction?: boolean;
|
|
26
|
+
}
|
|
27
|
+
declare function ssoSyncGuardMiddleware(options: SsoSyncGuardOptions): (req: Request, res: Response, next: NextFunction) => Promise<void>;
|
|
28
|
+
|
|
29
|
+
interface CreateSsoAuthRouterOptions {
|
|
30
|
+
ssoClient: BigsoSsoClient;
|
|
31
|
+
frontendUrl: string;
|
|
32
|
+
cookieName?: string;
|
|
33
|
+
cookieDomain?: string;
|
|
34
|
+
isProduction?: boolean;
|
|
35
|
+
onLoginSuccess?: (session: SsoSessionData) => void | Promise<void>;
|
|
36
|
+
onLogout?: (sessionToken: string) => void | Promise<void>;
|
|
37
|
+
}
|
|
38
|
+
declare function createSsoAuthRouter(options: CreateSsoAuthRouterOptions): Router;
|
|
39
|
+
|
|
40
|
+
interface SsoSyncRouterOptions {
|
|
41
|
+
resources: any[];
|
|
42
|
+
appId: string;
|
|
43
|
+
ssoBackendUrl: string;
|
|
44
|
+
isProduction?: boolean;
|
|
45
|
+
}
|
|
46
|
+
declare function createSsoSyncRouter(options: SsoSyncRouterOptions): Router;
|
|
47
|
+
|
|
48
|
+
export { type CreateSsoAuthRouterOptions, type SsoAuthMiddlewareOptions, type SsoSyncGuardOptions, type SsoSyncRouterOptions, createSsoAuthRouter, createSsoSyncRouter, ssoAuthMiddleware, ssoSyncGuardMiddleware };
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
// src/express/middlewares/ssoAuth.ts
|
|
2
|
+
function ssoAuthMiddleware(options) {
|
|
3
|
+
const cookieName = options.cookieName || "sso_session";
|
|
4
|
+
const isProduction = options.isProduction ?? process.env.NODE_ENV === "production";
|
|
5
|
+
return async (req, res, next) => {
|
|
6
|
+
try {
|
|
7
|
+
let sessionToken = req.cookies?.[cookieName];
|
|
8
|
+
let session = null;
|
|
9
|
+
if (sessionToken) {
|
|
10
|
+
session = await options.ssoClient.validateSessionToken(sessionToken);
|
|
11
|
+
}
|
|
12
|
+
if (!session) {
|
|
13
|
+
const refreshToken = req.cookies?.[`${cookieName}_refresh`];
|
|
14
|
+
if (refreshToken) {
|
|
15
|
+
const newSessionData = await options.ssoClient.refreshAppSession(refreshToken);
|
|
16
|
+
if (newSessionData) {
|
|
17
|
+
const sessionMaxAge = new Date(newSessionData.expiresAt).getTime() - Date.now();
|
|
18
|
+
const refreshMaxAge = newSessionData.refreshExpiresAt ? new Date(newSessionData.refreshExpiresAt).getTime() - Date.now() : 7 * 24 * 60 * 60 * 1e3;
|
|
19
|
+
const sessionCookieOptions = {
|
|
20
|
+
httpOnly: true,
|
|
21
|
+
secure: isProduction,
|
|
22
|
+
sameSite: "lax",
|
|
23
|
+
path: "/",
|
|
24
|
+
maxAge: sessionMaxAge > 0 ? sessionMaxAge : 0,
|
|
25
|
+
...isProduction && options.cookieDomain ? { domain: options.cookieDomain } : {}
|
|
26
|
+
};
|
|
27
|
+
const refreshCookieOptions = {
|
|
28
|
+
...sessionCookieOptions,
|
|
29
|
+
maxAge: refreshMaxAge > 0 ? refreshMaxAge : 0
|
|
30
|
+
};
|
|
31
|
+
res.cookie(cookieName, newSessionData.sessionToken, sessionCookieOptions);
|
|
32
|
+
res.cookie(`${cookieName}_refresh`, newSessionData.refreshToken, refreshCookieOptions);
|
|
33
|
+
session = await options.ssoClient.validateSessionToken(newSessionData.sessionToken);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
if (!session) {
|
|
37
|
+
res.clearCookie(cookieName);
|
|
38
|
+
res.clearCookie(`${cookieName}_refresh`);
|
|
39
|
+
res.status(401).json({ error: "Session expired or invalid" });
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
if (options.onSessionValidated) {
|
|
44
|
+
await options.onSessionValidated(session, req);
|
|
45
|
+
}
|
|
46
|
+
req.user = session.user;
|
|
47
|
+
req.tenant = session.tenant;
|
|
48
|
+
req.ssoSession = session;
|
|
49
|
+
next();
|
|
50
|
+
} catch (error) {
|
|
51
|
+
console.error("\u274C [BigsoAuthSDK] Authentication Middleware Error:", error instanceof Error ? error.message : error);
|
|
52
|
+
res.status(500).json({ error: "Internal authentication error" });
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// src/express/middlewares/ssoSyncGuard.ts
|
|
58
|
+
import { promises as dns } from "dns";
|
|
59
|
+
function ssoSyncGuardMiddleware(options) {
|
|
60
|
+
const isProduction = options.isProduction ?? process.env.NODE_ENV === "production";
|
|
61
|
+
return async (req, res, next) => {
|
|
62
|
+
try {
|
|
63
|
+
const isSecure = req.secure || req.headers["x-forwarded-proto"] === "https";
|
|
64
|
+
if (!isSecure && isProduction) {
|
|
65
|
+
console.warn("\u26A0\uFE0F [BigsoAuthSDK] Blocked non-HTTPS sync request");
|
|
66
|
+
res.status(403).json({ error: "HTTPS required" });
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
const clientIp = req.ip || req.socket.remoteAddress || "";
|
|
70
|
+
const isLoopback = clientIp === "::1" || clientIp === "127.0.0.1" || clientIp === "::ffff:127.0.0.1";
|
|
71
|
+
if (!isProduction && isLoopback) {
|
|
72
|
+
return next();
|
|
73
|
+
}
|
|
74
|
+
const ssoUrl = new URL(options.ssoBackendUrl);
|
|
75
|
+
const ssoHostname = ssoUrl.hostname;
|
|
76
|
+
const ssoIps = await dns.resolve4(ssoHostname).catch(() => []);
|
|
77
|
+
const cleanClientIp = clientIp.replace(/^.*:/, "");
|
|
78
|
+
const isPrivateIp = cleanClientIp.startsWith("10.") || cleanClientIp.startsWith("192.168.") || cleanClientIp.startsWith("172.") && parseInt(cleanClientIp.split(".")[1], 10) >= 16 && parseInt(cleanClientIp.split(".")[1], 10) <= 31;
|
|
79
|
+
if (!ssoIps.includes(cleanClientIp) && !isPrivateIp) {
|
|
80
|
+
console.warn(`\u26D4\uFE0F [BigsoAuthSDK] Blocked sync request from unauthorized IP: ${clientIp}`);
|
|
81
|
+
res.status(403).json({ error: "Unauthorized origin" });
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
next();
|
|
85
|
+
} catch (error) {
|
|
86
|
+
console.error("\u274C [BigsoAuthSDK] Sync Guard Validation Error:", error instanceof Error ? error.message : error);
|
|
87
|
+
res.status(500).json({ error: "Security validation failed" });
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// src/express/routes/createSsoAuthRouter.ts
|
|
93
|
+
import { Router } from "express";
|
|
94
|
+
function createSsoAuthRouter(options) {
|
|
95
|
+
const router = Router();
|
|
96
|
+
const cookieName = options.cookieName || "sso_session";
|
|
97
|
+
const isProduction = options.isProduction ?? process.env.NODE_ENV === "production";
|
|
98
|
+
const getCookieOptions = (customOptions = {}) => {
|
|
99
|
+
const base = {
|
|
100
|
+
httpOnly: true,
|
|
101
|
+
secure: isProduction,
|
|
102
|
+
sameSite: "lax",
|
|
103
|
+
path: "/",
|
|
104
|
+
...customOptions
|
|
105
|
+
};
|
|
106
|
+
if (isProduction && options.cookieDomain) {
|
|
107
|
+
base.domain = options.cookieDomain;
|
|
108
|
+
}
|
|
109
|
+
return base;
|
|
110
|
+
};
|
|
111
|
+
router.post("/exchange", async (req, res) => {
|
|
112
|
+
try {
|
|
113
|
+
const { code } = req.body;
|
|
114
|
+
if (!code) {
|
|
115
|
+
res.status(400).json({ error: "Authorization code is required" });
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
const ssoResponse = await options.ssoClient.exchangeCodeForToken(code);
|
|
119
|
+
if (!ssoResponse.success) {
|
|
120
|
+
res.status(401).json({ error: "Invalid authorization code" });
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
const sessionMaxAge = new Date(ssoResponse.expiresAt).getTime() - Date.now();
|
|
124
|
+
const refreshMaxAge = ssoResponse.refreshExpiresAt ? new Date(ssoResponse.refreshExpiresAt).getTime() - Date.now() : 7 * 24 * 60 * 60 * 1e3;
|
|
125
|
+
const sessionCookieOptions = getCookieOptions({
|
|
126
|
+
maxAge: sessionMaxAge > 0 ? sessionMaxAge : 0
|
|
127
|
+
});
|
|
128
|
+
const refreshCookieOptions = getCookieOptions({
|
|
129
|
+
maxAge: refreshMaxAge > 0 ? refreshMaxAge : 0
|
|
130
|
+
});
|
|
131
|
+
res.cookie(cookieName, ssoResponse.sessionToken, sessionCookieOptions);
|
|
132
|
+
if (ssoResponse.refreshToken) {
|
|
133
|
+
res.cookie(`${cookieName}_refresh`, ssoResponse.refreshToken, refreshCookieOptions);
|
|
134
|
+
}
|
|
135
|
+
if (options.onLoginSuccess) {
|
|
136
|
+
await options.onLoginSuccess(ssoResponse);
|
|
137
|
+
}
|
|
138
|
+
res.json({
|
|
139
|
+
success: true,
|
|
140
|
+
user: ssoResponse.user,
|
|
141
|
+
tenant: ssoResponse.tenant,
|
|
142
|
+
expiresAt: ssoResponse.expiresAt
|
|
143
|
+
});
|
|
144
|
+
} catch (error) {
|
|
145
|
+
console.error("\u274C [BigsoAuthSDK] Error exchanging code:", error.message);
|
|
146
|
+
res.status(500).json({
|
|
147
|
+
error: error.message || "Failed to exchange authorization code"
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
router.post("/exchange-v2", async (req, res) => {
|
|
152
|
+
try {
|
|
153
|
+
const { payload } = req.body;
|
|
154
|
+
if (!payload) {
|
|
155
|
+
res.status(400).json({ error: "Signed payload is required" });
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
const verified = await options.ssoClient.verifySignedPayload(payload, options.frontendUrl);
|
|
159
|
+
if (!verified.code) {
|
|
160
|
+
res.status(400).json({ error: "No authorization code found in payload" });
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
const ssoResponse = await options.ssoClient.exchangeCodeForToken(verified.code);
|
|
164
|
+
if (!ssoResponse.success) {
|
|
165
|
+
res.status(401).json({ error: "Invalid authorization code" });
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
const sessionMaxAge = new Date(ssoResponse.expiresAt).getTime() - Date.now();
|
|
169
|
+
const refreshMaxAge = ssoResponse.refreshExpiresAt ? new Date(ssoResponse.refreshExpiresAt).getTime() - Date.now() : 7 * 24 * 60 * 60 * 1e3;
|
|
170
|
+
const sessionCookieOptions = getCookieOptions({
|
|
171
|
+
maxAge: sessionMaxAge > 0 ? sessionMaxAge : 0
|
|
172
|
+
});
|
|
173
|
+
const refreshCookieOptions = getCookieOptions({
|
|
174
|
+
maxAge: refreshMaxAge > 0 ? refreshMaxAge : 0
|
|
175
|
+
});
|
|
176
|
+
res.cookie(cookieName, ssoResponse.sessionToken, sessionCookieOptions);
|
|
177
|
+
if (ssoResponse.refreshToken) {
|
|
178
|
+
res.cookie(`${cookieName}_refresh`, ssoResponse.refreshToken, refreshCookieOptions);
|
|
179
|
+
}
|
|
180
|
+
if (options.onLoginSuccess) {
|
|
181
|
+
await options.onLoginSuccess(ssoResponse);
|
|
182
|
+
}
|
|
183
|
+
res.json({
|
|
184
|
+
success: true,
|
|
185
|
+
user: ssoResponse.user,
|
|
186
|
+
tenant: ssoResponse.tenant,
|
|
187
|
+
expiresAt: ssoResponse.expiresAt
|
|
188
|
+
});
|
|
189
|
+
} catch (error) {
|
|
190
|
+
console.error("\u274C [BigsoAuthSDK] Error exchanging v2 payload:", error.message);
|
|
191
|
+
res.status(401).json({
|
|
192
|
+
error: error.message || "Failed to verify signed payload"
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
});
|
|
196
|
+
router.get("/session", ssoAuthMiddleware(options), (req, res) => {
|
|
197
|
+
res.set("Cache-Control", "no-store, no-cache, must-revalidate, private");
|
|
198
|
+
res.set("Pragma", "no-cache");
|
|
199
|
+
res.set("Expires", "0");
|
|
200
|
+
res.json({
|
|
201
|
+
success: true,
|
|
202
|
+
user: req.user,
|
|
203
|
+
tenant: req.tenant,
|
|
204
|
+
expiresAt: req.ssoSession?.expiresAt
|
|
205
|
+
});
|
|
206
|
+
});
|
|
207
|
+
router.post("/logout", async (req, res) => {
|
|
208
|
+
const sessionToken = req.cookies?.[cookieName];
|
|
209
|
+
if (sessionToken) {
|
|
210
|
+
try {
|
|
211
|
+
await options.ssoClient.revokeSession(sessionToken);
|
|
212
|
+
} catch (error) {
|
|
213
|
+
console.warn("\u26A0\uFE0F [BigsoAuthSDK] Failed to revoke session in SSO Backend. Clearing local anyway.", error.message);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
const cookieOptions = getCookieOptions({ maxAge: 0 });
|
|
217
|
+
res.clearCookie(cookieName, cookieOptions);
|
|
218
|
+
res.clearCookie(`${cookieName}_refresh`, cookieOptions);
|
|
219
|
+
if (options.onLogout && sessionToken) {
|
|
220
|
+
await options.onLogout(sessionToken);
|
|
221
|
+
}
|
|
222
|
+
res.json({ success: true, message: "Logged out" });
|
|
223
|
+
});
|
|
224
|
+
return router;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// src/express/routes/createSsoSyncRouter.ts
|
|
228
|
+
import { Router as Router2 } from "express";
|
|
229
|
+
function createSsoSyncRouter(options) {
|
|
230
|
+
const router = Router2();
|
|
231
|
+
router.get("/resources", ssoSyncGuardMiddleware({
|
|
232
|
+
ssoBackendUrl: options.ssoBackendUrl,
|
|
233
|
+
isProduction: options.isProduction
|
|
234
|
+
}), (req, res) => {
|
|
235
|
+
try {
|
|
236
|
+
res.json({
|
|
237
|
+
success: true,
|
|
238
|
+
resources: options.resources,
|
|
239
|
+
meta: {
|
|
240
|
+
appId: options.appId,
|
|
241
|
+
count: options.resources.length,
|
|
242
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
243
|
+
}
|
|
244
|
+
});
|
|
245
|
+
} catch (error) {
|
|
246
|
+
console.error("\u274C [BigsoAuthSDK] Error in sync endpoint:", error.message);
|
|
247
|
+
res.status(500).json({ error: error.message });
|
|
248
|
+
}
|
|
249
|
+
});
|
|
250
|
+
return router;
|
|
251
|
+
}
|
|
252
|
+
export {
|
|
253
|
+
createSsoAuthRouter,
|
|
254
|
+
createSsoSyncRouter,
|
|
255
|
+
ssoAuthMiddleware,
|
|
256
|
+
ssoSyncGuardMiddleware
|
|
257
|
+
};
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/node/index.ts
|
|
21
|
+
var node_exports = {};
|
|
22
|
+
__export(node_exports, {
|
|
23
|
+
BigsoSsoClient: () => BigsoSsoClient
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(node_exports);
|
|
26
|
+
|
|
27
|
+
// src/utils/jws.ts
|
|
28
|
+
var import_jose = require("jose");
|
|
29
|
+
async function verifySignedPayload(token, jwksUrl, expectedAudience) {
|
|
30
|
+
const JWKS = (0, import_jose.createRemoteJWKSet)(new URL(jwksUrl));
|
|
31
|
+
const { payload } = await (0, import_jose.jwtVerify)(token, JWKS, {
|
|
32
|
+
audience: expectedAudience
|
|
33
|
+
});
|
|
34
|
+
return payload;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// src/node/SsoClient.ts
|
|
38
|
+
var BigsoSsoClient = class {
|
|
39
|
+
constructor(options) {
|
|
40
|
+
this.ssoBackendUrl = options.ssoBackendUrl;
|
|
41
|
+
this.appId = options.appId;
|
|
42
|
+
this.ssoJwksUrl = options.ssoJwksUrl;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Verify a signed payload (JWS) against the SSO's JWKS
|
|
46
|
+
* @param token - The compact JWS token
|
|
47
|
+
* @param expectedAudience - The expected audience (app origin)
|
|
48
|
+
* @returns The verified payload
|
|
49
|
+
*/
|
|
50
|
+
async verifySignedPayload(token, expectedAudience) {
|
|
51
|
+
if (!this.ssoJwksUrl) {
|
|
52
|
+
throw new Error("ssoJwksUrl is required for verifySignedPayload");
|
|
53
|
+
}
|
|
54
|
+
return await verifySignedPayload(token, this.ssoJwksUrl, expectedAudience);
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Validate session token with SSO Backend
|
|
58
|
+
* @param sessionToken - JWT token from cookie
|
|
59
|
+
* @returns Session data or null if invalid
|
|
60
|
+
*/
|
|
61
|
+
async validateSessionToken(sessionToken) {
|
|
62
|
+
try {
|
|
63
|
+
const response = await fetch(`${this.ssoBackendUrl}/api/v1/auth/verify-session`, {
|
|
64
|
+
method: "POST",
|
|
65
|
+
headers: {
|
|
66
|
+
"Content-Type": "application/json"
|
|
67
|
+
},
|
|
68
|
+
body: JSON.stringify({
|
|
69
|
+
sessionToken,
|
|
70
|
+
appId: this.appId
|
|
71
|
+
})
|
|
72
|
+
// Node 18+ allows abort signals to enforce timeout, but we will rely on native fetch timeout if available or no timeout for simplicity.
|
|
73
|
+
// In production, we might want to implement an AbortController wrapper.
|
|
74
|
+
});
|
|
75
|
+
if (!response.ok) {
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
const data = await response.json();
|
|
79
|
+
if (data.valid) {
|
|
80
|
+
return {
|
|
81
|
+
user: data.user,
|
|
82
|
+
tenant: data.tenant,
|
|
83
|
+
appId: data.appId,
|
|
84
|
+
expiresAt: data.expiresAt
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
return null;
|
|
88
|
+
} catch (error) {
|
|
89
|
+
console.error("\u274C [BigsoSsoClient] Error validating session:", error instanceof Error ? error.message : error);
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Exchange authorization code for session token from SSO
|
|
95
|
+
* @param code - The auth code
|
|
96
|
+
* @returns The SSO exchange response
|
|
97
|
+
*/
|
|
98
|
+
async exchangeCodeForToken(code) {
|
|
99
|
+
const response = await fetch(`${this.ssoBackendUrl}/api/v1/auth/token`, {
|
|
100
|
+
method: "POST",
|
|
101
|
+
headers: {
|
|
102
|
+
"Content-Type": "application/json"
|
|
103
|
+
},
|
|
104
|
+
body: JSON.stringify({
|
|
105
|
+
authCode: code,
|
|
106
|
+
appId: this.appId
|
|
107
|
+
})
|
|
108
|
+
});
|
|
109
|
+
if (!response.ok) {
|
|
110
|
+
const errData = await response.json().catch(() => ({}));
|
|
111
|
+
throw new Error(errData.message || "Failed to exchange token");
|
|
112
|
+
}
|
|
113
|
+
return await response.json();
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Revoke session in SSO backend
|
|
117
|
+
* @param sessionToken - The active session token
|
|
118
|
+
*/
|
|
119
|
+
async revokeSession(sessionToken) {
|
|
120
|
+
const response = await fetch(`${this.ssoBackendUrl}/api/v1/session/revoke`, {
|
|
121
|
+
method: "POST",
|
|
122
|
+
headers: {
|
|
123
|
+
"Content-Type": "application/json",
|
|
124
|
+
"Authorization": `Bearer ${sessionToken}`
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
if (!response.ok) {
|
|
128
|
+
throw new Error("Failed to revoke session");
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Refreshes the application session using a refresh token
|
|
133
|
+
* @param refreshToken - The stored refresh token
|
|
134
|
+
* @returns The new session tokens or null if failed
|
|
135
|
+
*/
|
|
136
|
+
async refreshAppSession(refreshToken) {
|
|
137
|
+
try {
|
|
138
|
+
const response = await fetch(`${this.ssoBackendUrl}/api/v1/auth/app-refresh`, {
|
|
139
|
+
method: "POST",
|
|
140
|
+
headers: {
|
|
141
|
+
"Content-Type": "application/json"
|
|
142
|
+
},
|
|
143
|
+
body: JSON.stringify({
|
|
144
|
+
refreshToken,
|
|
145
|
+
appId: this.appId
|
|
146
|
+
})
|
|
147
|
+
});
|
|
148
|
+
if (!response.ok) {
|
|
149
|
+
return null;
|
|
150
|
+
}
|
|
151
|
+
const data = await response.json();
|
|
152
|
+
if (data.success) {
|
|
153
|
+
return {
|
|
154
|
+
sessionToken: data.sessionToken,
|
|
155
|
+
refreshToken: data.refreshToken,
|
|
156
|
+
expiresAt: data.expiresAt,
|
|
157
|
+
refreshExpiresAt: data.refreshExpiresAt
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
return null;
|
|
161
|
+
} catch (error) {
|
|
162
|
+
console.error("\u274C [BigsoSsoClient] Error refreshing app session:", error instanceof Error ? error.message : error);
|
|
163
|
+
return null;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
168
|
+
0 && (module.exports = {
|
|
169
|
+
BigsoSsoClient
|
|
170
|
+
});
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { S as SsoSessionData, a as SsoExchangeResponse, b as SsoRefreshData } from '../types-CoXgtTry.cjs';
|
|
2
|
+
|
|
3
|
+
interface SsoClientOptions {
|
|
4
|
+
ssoBackendUrl: string;
|
|
5
|
+
ssoJwksUrl?: string;
|
|
6
|
+
appId: string;
|
|
7
|
+
}
|
|
8
|
+
declare class BigsoSsoClient {
|
|
9
|
+
private ssoBackendUrl;
|
|
10
|
+
private appId;
|
|
11
|
+
private ssoJwksUrl?;
|
|
12
|
+
constructor(options: SsoClientOptions);
|
|
13
|
+
/**
|
|
14
|
+
* Verify a signed payload (JWS) against the SSO's JWKS
|
|
15
|
+
* @param token - The compact JWS token
|
|
16
|
+
* @param expectedAudience - The expected audience (app origin)
|
|
17
|
+
* @returns The verified payload
|
|
18
|
+
*/
|
|
19
|
+
verifySignedPayload(token: string, expectedAudience: string): Promise<any>;
|
|
20
|
+
/**
|
|
21
|
+
* Validate session token with SSO Backend
|
|
22
|
+
* @param sessionToken - JWT token from cookie
|
|
23
|
+
* @returns Session data or null if invalid
|
|
24
|
+
*/
|
|
25
|
+
validateSessionToken(sessionToken: string): Promise<SsoSessionData | null>;
|
|
26
|
+
/**
|
|
27
|
+
* Exchange authorization code for session token from SSO
|
|
28
|
+
* @param code - The auth code
|
|
29
|
+
* @returns The SSO exchange response
|
|
30
|
+
*/
|
|
31
|
+
exchangeCodeForToken(code: string): Promise<SsoExchangeResponse>;
|
|
32
|
+
/**
|
|
33
|
+
* Revoke session in SSO backend
|
|
34
|
+
* @param sessionToken - The active session token
|
|
35
|
+
*/
|
|
36
|
+
revokeSession(sessionToken: string): Promise<void>;
|
|
37
|
+
/**
|
|
38
|
+
* Refreshes the application session using a refresh token
|
|
39
|
+
* @param refreshToken - The stored refresh token
|
|
40
|
+
* @returns The new session tokens or null if failed
|
|
41
|
+
*/
|
|
42
|
+
refreshAppSession(refreshToken: string): Promise<SsoRefreshData | null>;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export { BigsoSsoClient, type SsoClientOptions };
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { S as SsoSessionData, a as SsoExchangeResponse, b as SsoRefreshData } from '../types-CoXgtTry.js';
|
|
2
|
+
|
|
3
|
+
interface SsoClientOptions {
|
|
4
|
+
ssoBackendUrl: string;
|
|
5
|
+
ssoJwksUrl?: string;
|
|
6
|
+
appId: string;
|
|
7
|
+
}
|
|
8
|
+
declare class BigsoSsoClient {
|
|
9
|
+
private ssoBackendUrl;
|
|
10
|
+
private appId;
|
|
11
|
+
private ssoJwksUrl?;
|
|
12
|
+
constructor(options: SsoClientOptions);
|
|
13
|
+
/**
|
|
14
|
+
* Verify a signed payload (JWS) against the SSO's JWKS
|
|
15
|
+
* @param token - The compact JWS token
|
|
16
|
+
* @param expectedAudience - The expected audience (app origin)
|
|
17
|
+
* @returns The verified payload
|
|
18
|
+
*/
|
|
19
|
+
verifySignedPayload(token: string, expectedAudience: string): Promise<any>;
|
|
20
|
+
/**
|
|
21
|
+
* Validate session token with SSO Backend
|
|
22
|
+
* @param sessionToken - JWT token from cookie
|
|
23
|
+
* @returns Session data or null if invalid
|
|
24
|
+
*/
|
|
25
|
+
validateSessionToken(sessionToken: string): Promise<SsoSessionData | null>;
|
|
26
|
+
/**
|
|
27
|
+
* Exchange authorization code for session token from SSO
|
|
28
|
+
* @param code - The auth code
|
|
29
|
+
* @returns The SSO exchange response
|
|
30
|
+
*/
|
|
31
|
+
exchangeCodeForToken(code: string): Promise<SsoExchangeResponse>;
|
|
32
|
+
/**
|
|
33
|
+
* Revoke session in SSO backend
|
|
34
|
+
* @param sessionToken - The active session token
|
|
35
|
+
*/
|
|
36
|
+
revokeSession(sessionToken: string): Promise<void>;
|
|
37
|
+
/**
|
|
38
|
+
* Refreshes the application session using a refresh token
|
|
39
|
+
* @param refreshToken - The stored refresh token
|
|
40
|
+
* @returns The new session tokens or null if failed
|
|
41
|
+
*/
|
|
42
|
+
refreshAppSession(refreshToken: string): Promise<SsoRefreshData | null>;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export { BigsoSsoClient, type SsoClientOptions };
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import {
|
|
2
|
+
verifySignedPayload
|
|
3
|
+
} from "../chunk-LDDK6SJD.js";
|
|
4
|
+
|
|
5
|
+
// src/node/SsoClient.ts
|
|
6
|
+
var BigsoSsoClient = class {
|
|
7
|
+
constructor(options) {
|
|
8
|
+
this.ssoBackendUrl = options.ssoBackendUrl;
|
|
9
|
+
this.appId = options.appId;
|
|
10
|
+
this.ssoJwksUrl = options.ssoJwksUrl;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Verify a signed payload (JWS) against the SSO's JWKS
|
|
14
|
+
* @param token - The compact JWS token
|
|
15
|
+
* @param expectedAudience - The expected audience (app origin)
|
|
16
|
+
* @returns The verified payload
|
|
17
|
+
*/
|
|
18
|
+
async verifySignedPayload(token, expectedAudience) {
|
|
19
|
+
if (!this.ssoJwksUrl) {
|
|
20
|
+
throw new Error("ssoJwksUrl is required for verifySignedPayload");
|
|
21
|
+
}
|
|
22
|
+
return await verifySignedPayload(token, this.ssoJwksUrl, expectedAudience);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Validate session token with SSO Backend
|
|
26
|
+
* @param sessionToken - JWT token from cookie
|
|
27
|
+
* @returns Session data or null if invalid
|
|
28
|
+
*/
|
|
29
|
+
async validateSessionToken(sessionToken) {
|
|
30
|
+
try {
|
|
31
|
+
const response = await fetch(`${this.ssoBackendUrl}/api/v1/auth/verify-session`, {
|
|
32
|
+
method: "POST",
|
|
33
|
+
headers: {
|
|
34
|
+
"Content-Type": "application/json"
|
|
35
|
+
},
|
|
36
|
+
body: JSON.stringify({
|
|
37
|
+
sessionToken,
|
|
38
|
+
appId: this.appId
|
|
39
|
+
})
|
|
40
|
+
// Node 18+ allows abort signals to enforce timeout, but we will rely on native fetch timeout if available or no timeout for simplicity.
|
|
41
|
+
// In production, we might want to implement an AbortController wrapper.
|
|
42
|
+
});
|
|
43
|
+
if (!response.ok) {
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
const data = await response.json();
|
|
47
|
+
if (data.valid) {
|
|
48
|
+
return {
|
|
49
|
+
user: data.user,
|
|
50
|
+
tenant: data.tenant,
|
|
51
|
+
appId: data.appId,
|
|
52
|
+
expiresAt: data.expiresAt
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
return null;
|
|
56
|
+
} catch (error) {
|
|
57
|
+
console.error("\u274C [BigsoSsoClient] Error validating session:", error instanceof Error ? error.message : error);
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Exchange authorization code for session token from SSO
|
|
63
|
+
* @param code - The auth code
|
|
64
|
+
* @returns The SSO exchange response
|
|
65
|
+
*/
|
|
66
|
+
async exchangeCodeForToken(code) {
|
|
67
|
+
const response = await fetch(`${this.ssoBackendUrl}/api/v1/auth/token`, {
|
|
68
|
+
method: "POST",
|
|
69
|
+
headers: {
|
|
70
|
+
"Content-Type": "application/json"
|
|
71
|
+
},
|
|
72
|
+
body: JSON.stringify({
|
|
73
|
+
authCode: code,
|
|
74
|
+
appId: this.appId
|
|
75
|
+
})
|
|
76
|
+
});
|
|
77
|
+
if (!response.ok) {
|
|
78
|
+
const errData = await response.json().catch(() => ({}));
|
|
79
|
+
throw new Error(errData.message || "Failed to exchange token");
|
|
80
|
+
}
|
|
81
|
+
return await response.json();
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Revoke session in SSO backend
|
|
85
|
+
* @param sessionToken - The active session token
|
|
86
|
+
*/
|
|
87
|
+
async revokeSession(sessionToken) {
|
|
88
|
+
const response = await fetch(`${this.ssoBackendUrl}/api/v1/session/revoke`, {
|
|
89
|
+
method: "POST",
|
|
90
|
+
headers: {
|
|
91
|
+
"Content-Type": "application/json",
|
|
92
|
+
"Authorization": `Bearer ${sessionToken}`
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
if (!response.ok) {
|
|
96
|
+
throw new Error("Failed to revoke session");
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Refreshes the application session using a refresh token
|
|
101
|
+
* @param refreshToken - The stored refresh token
|
|
102
|
+
* @returns The new session tokens or null if failed
|
|
103
|
+
*/
|
|
104
|
+
async refreshAppSession(refreshToken) {
|
|
105
|
+
try {
|
|
106
|
+
const response = await fetch(`${this.ssoBackendUrl}/api/v1/auth/app-refresh`, {
|
|
107
|
+
method: "POST",
|
|
108
|
+
headers: {
|
|
109
|
+
"Content-Type": "application/json"
|
|
110
|
+
},
|
|
111
|
+
body: JSON.stringify({
|
|
112
|
+
refreshToken,
|
|
113
|
+
appId: this.appId
|
|
114
|
+
})
|
|
115
|
+
});
|
|
116
|
+
if (!response.ok) {
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
const data = await response.json();
|
|
120
|
+
if (data.success) {
|
|
121
|
+
return {
|
|
122
|
+
sessionToken: data.sessionToken,
|
|
123
|
+
refreshToken: data.refreshToken,
|
|
124
|
+
expiresAt: data.expiresAt,
|
|
125
|
+
refreshExpiresAt: data.refreshExpiresAt
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
return null;
|
|
129
|
+
} catch (error) {
|
|
130
|
+
console.error("\u274C [BigsoSsoClient] Error refreshing app session:", error instanceof Error ? error.message : error);
|
|
131
|
+
return null;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
export {
|
|
136
|
+
BigsoSsoClient
|
|
137
|
+
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
interface BigsoAuthOptions {
|
|
2
|
+
/** Client ID registrado en el SSO */
|
|
3
|
+
clientId: string;
|
|
4
|
+
/** Origen del SSO (ej: https://sso.bigso.co) */
|
|
5
|
+
ssoOrigin: string;
|
|
6
|
+
/** URL del JWKS para verificar firmas (ej: https://sso.bigso.co/.well-known/jwks.json) */
|
|
7
|
+
jwksUrl: string;
|
|
8
|
+
/** Timeout en milisegundos (por defecto 5000) */
|
|
9
|
+
timeout?: number;
|
|
10
|
+
/** Activar logs de depuración */
|
|
11
|
+
debug?: boolean;
|
|
12
|
+
/** URI de redirección registrada (opcional, si se requiere validación exacta) */
|
|
13
|
+
redirectUri?: string;
|
|
14
|
+
/** Sugerencia de tenant (opcional) */
|
|
15
|
+
tenantHint?: string;
|
|
16
|
+
/** Tema visual del iframe ('light' | 'dark', por defecto 'light') */
|
|
17
|
+
theme?: 'light' | 'dark';
|
|
18
|
+
}
|
|
19
|
+
interface SsoUser {
|
|
20
|
+
userId: string;
|
|
21
|
+
email: string;
|
|
22
|
+
firstName: string;
|
|
23
|
+
lastName: string;
|
|
24
|
+
}
|
|
25
|
+
interface SsoTenant {
|
|
26
|
+
tenantId: string;
|
|
27
|
+
name: string;
|
|
28
|
+
slug: string;
|
|
29
|
+
role: string;
|
|
30
|
+
permissions: string[];
|
|
31
|
+
}
|
|
32
|
+
interface SsoSessionData {
|
|
33
|
+
user: SsoUser;
|
|
34
|
+
tenant: SsoTenant;
|
|
35
|
+
appId: string;
|
|
36
|
+
expiresAt: string;
|
|
37
|
+
}
|
|
38
|
+
interface SsoRefreshData {
|
|
39
|
+
sessionToken: string;
|
|
40
|
+
refreshToken: string;
|
|
41
|
+
expiresAt: string;
|
|
42
|
+
refreshExpiresAt: string;
|
|
43
|
+
}
|
|
44
|
+
interface SsoExchangeResponse extends SsoSessionData {
|
|
45
|
+
success: boolean;
|
|
46
|
+
sessionToken: string;
|
|
47
|
+
refreshToken?: string;
|
|
48
|
+
refreshExpiresAt?: string;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export type { BigsoAuthOptions as B, SsoSessionData as S, SsoExchangeResponse as a, SsoRefreshData as b };
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
interface BigsoAuthOptions {
|
|
2
|
+
/** Client ID registrado en el SSO */
|
|
3
|
+
clientId: string;
|
|
4
|
+
/** Origen del SSO (ej: https://sso.bigso.co) */
|
|
5
|
+
ssoOrigin: string;
|
|
6
|
+
/** URL del JWKS para verificar firmas (ej: https://sso.bigso.co/.well-known/jwks.json) */
|
|
7
|
+
jwksUrl: string;
|
|
8
|
+
/** Timeout en milisegundos (por defecto 5000) */
|
|
9
|
+
timeout?: number;
|
|
10
|
+
/** Activar logs de depuración */
|
|
11
|
+
debug?: boolean;
|
|
12
|
+
/** URI de redirección registrada (opcional, si se requiere validación exacta) */
|
|
13
|
+
redirectUri?: string;
|
|
14
|
+
/** Sugerencia de tenant (opcional) */
|
|
15
|
+
tenantHint?: string;
|
|
16
|
+
/** Tema visual del iframe ('light' | 'dark', por defecto 'light') */
|
|
17
|
+
theme?: 'light' | 'dark';
|
|
18
|
+
}
|
|
19
|
+
interface SsoUser {
|
|
20
|
+
userId: string;
|
|
21
|
+
email: string;
|
|
22
|
+
firstName: string;
|
|
23
|
+
lastName: string;
|
|
24
|
+
}
|
|
25
|
+
interface SsoTenant {
|
|
26
|
+
tenantId: string;
|
|
27
|
+
name: string;
|
|
28
|
+
slug: string;
|
|
29
|
+
role: string;
|
|
30
|
+
permissions: string[];
|
|
31
|
+
}
|
|
32
|
+
interface SsoSessionData {
|
|
33
|
+
user: SsoUser;
|
|
34
|
+
tenant: SsoTenant;
|
|
35
|
+
appId: string;
|
|
36
|
+
expiresAt: string;
|
|
37
|
+
}
|
|
38
|
+
interface SsoRefreshData {
|
|
39
|
+
sessionToken: string;
|
|
40
|
+
refreshToken: string;
|
|
41
|
+
expiresAt: string;
|
|
42
|
+
refreshExpiresAt: string;
|
|
43
|
+
}
|
|
44
|
+
interface SsoExchangeResponse extends SsoSessionData {
|
|
45
|
+
success: boolean;
|
|
46
|
+
sessionToken: string;
|
|
47
|
+
refreshToken?: string;
|
|
48
|
+
refreshExpiresAt?: string;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export type { BigsoAuthOptions as B, SsoSessionData as S, SsoExchangeResponse as a, SsoRefreshData as b };
|
package/package.json
CHANGED
|
@@ -1,20 +1,43 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bigso/auth-sdk",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.6",
|
|
4
4
|
"description": "SDK de autenticación para SSO v2.3 con iframe seguro",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"registry": "https://registry.npmjs.org/",
|
|
7
7
|
"access": "public"
|
|
8
8
|
},
|
|
9
9
|
"type": "module",
|
|
10
|
-
"
|
|
11
|
-
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"types": "./dist/browser/index.d.ts",
|
|
13
|
+
"import": "./dist/browser/index.js",
|
|
14
|
+
"require": "./dist/browser/index.cjs"
|
|
15
|
+
},
|
|
16
|
+
"./browser": {
|
|
17
|
+
"types": "./dist/browser/index.d.ts",
|
|
18
|
+
"import": "./dist/browser/index.js",
|
|
19
|
+
"require": "./dist/browser/index.cjs"
|
|
20
|
+
},
|
|
21
|
+
"./node": {
|
|
22
|
+
"types": "./dist/node/index.d.ts",
|
|
23
|
+
"import": "./dist/node/index.js",
|
|
24
|
+
"require": "./dist/node/index.cjs"
|
|
25
|
+
},
|
|
26
|
+
"./express": {
|
|
27
|
+
"types": "./dist/express/index.d.ts",
|
|
28
|
+
"import": "./dist/express/index.js",
|
|
29
|
+
"require": "./dist/express/index.cjs"
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"main": "dist/browser/index.cjs",
|
|
33
|
+
"module": "dist/browser/index.js",
|
|
34
|
+
"types": "dist/browser/index.d.ts",
|
|
12
35
|
"files": [
|
|
13
36
|
"dist"
|
|
14
37
|
],
|
|
15
38
|
"scripts": {
|
|
16
|
-
"build": "tsup src/index.ts --format esm,cjs --dts",
|
|
17
|
-
"dev": "tsup src/index.ts --watch",
|
|
39
|
+
"build": "tsup src/browser/index.ts src/node/index.ts src/express/index.ts --format esm,cjs --dts --out-dir dist",
|
|
40
|
+
"dev": "tsup src/browser/index.ts src/node/index.ts src/express/index.ts --watch --out-dir dist",
|
|
18
41
|
"lint": "eslint .",
|
|
19
42
|
"test": "vitest",
|
|
20
43
|
"release": "git tag v$npm_package_version && git push origin v$npm_package_version"
|
|
@@ -22,10 +45,15 @@
|
|
|
22
45
|
"dependencies": {
|
|
23
46
|
"jose": "^5.0.0"
|
|
24
47
|
},
|
|
48
|
+
"peerDependencies": {
|
|
49
|
+
"express": "^4.0.0"
|
|
50
|
+
},
|
|
25
51
|
"devDependencies": {
|
|
52
|
+
"@types/express": "^4.17.21",
|
|
53
|
+
"eslint": "^9.0.0",
|
|
54
|
+
"express": "^5.2.1",
|
|
26
55
|
"tsup": "^8.0.0",
|
|
27
56
|
"typescript": "^5.0.0",
|
|
28
|
-
"eslint": "^9.0.0",
|
|
29
57
|
"vitest": "^1.0.0"
|
|
30
58
|
},
|
|
31
59
|
"keywords": [
|