cynx-lib 1.3.41 → 1.3.44
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/index.cjs +2 -0
- package/package.json +33 -9
- package/ui/index.cjs +182 -0
- package/utils/index.cjs +80 -0
- package/utils/utils/db.cjs +779 -0
- package/utils/utils/duration.cjs +119 -0
- package/utils/utils/oidc.cjs +164 -0
- package/utils/utils/realtime.cjs +881 -0
- package/utils/utils/session.cjs +61 -0
- package/utils/utils/storage.cjs +344 -0
- package/utils/utils/storage_manager.cjs +1177 -0
- package/utils/utils/tz.cjs +542 -0
- package/utils/utils/ui.cjs +105 -0
- package/utils/utils/uid.cjs +187 -0
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __export = (target, all) => {
|
|
6
|
+
for (var name in all)
|
|
7
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
8
|
+
};
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
+
}
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
18
|
+
var duration_exports = {};
|
|
19
|
+
__export(duration_exports, {
|
|
20
|
+
default: () => duration_default,
|
|
21
|
+
formatDurationLabel: () => formatDurationLabel,
|
|
22
|
+
formatDurationTag: () => formatDurationTag,
|
|
23
|
+
parseDurationMs: () => parseDurationMs,
|
|
24
|
+
parseDurationToSeconds: () => parseDurationToSeconds
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(duration_exports);
|
|
27
|
+
function parseDurationToSeconds(input, minSeconds = 60) {
|
|
28
|
+
if (input === null || input === void 0 || input === "") {
|
|
29
|
+
return minSeconds;
|
|
30
|
+
}
|
|
31
|
+
if (typeof input === "number") {
|
|
32
|
+
if (isNaN(input) || input <= 0) return minSeconds;
|
|
33
|
+
return Math.max(minSeconds, Math.round(input));
|
|
34
|
+
}
|
|
35
|
+
const str = String(input).trim().toLowerCase();
|
|
36
|
+
if (/^\d+$/.test(str)) {
|
|
37
|
+
const num = parseInt(str, 10);
|
|
38
|
+
return Math.max(minSeconds, num);
|
|
39
|
+
}
|
|
40
|
+
const match = str.match(/^(\d+(?:\.\d+)?)\s*(mo|w|d|h|m|s)?$/);
|
|
41
|
+
if (!match) {
|
|
42
|
+
return minSeconds;
|
|
43
|
+
}
|
|
44
|
+
const val = parseFloat(match[1]);
|
|
45
|
+
const unit = match[2] || "s";
|
|
46
|
+
let totalSec = 0;
|
|
47
|
+
switch (unit) {
|
|
48
|
+
case "mo":
|
|
49
|
+
totalSec = val * 30 * 86400;
|
|
50
|
+
break;
|
|
51
|
+
case "w":
|
|
52
|
+
totalSec = val * 7 * 86400;
|
|
53
|
+
break;
|
|
54
|
+
case "d":
|
|
55
|
+
totalSec = val * 86400;
|
|
56
|
+
break;
|
|
57
|
+
case "h":
|
|
58
|
+
totalSec = val * 3600;
|
|
59
|
+
break;
|
|
60
|
+
case "m":
|
|
61
|
+
totalSec = val * 60;
|
|
62
|
+
break;
|
|
63
|
+
case "s":
|
|
64
|
+
default:
|
|
65
|
+
totalSec = val;
|
|
66
|
+
break;
|
|
67
|
+
}
|
|
68
|
+
const rounded = Math.round(totalSec);
|
|
69
|
+
return Math.max(minSeconds, rounded);
|
|
70
|
+
}
|
|
71
|
+
function parseDurationMs(val, defaultMs = 30 * 24 * 60 * 60 * 1e3) {
|
|
72
|
+
if (!val || val === "off" || val === "0" || val === 0) return 0;
|
|
73
|
+
if (typeof val === "number") return val > 0 ? val : defaultMs;
|
|
74
|
+
const str = String(val).trim().toLowerCase();
|
|
75
|
+
const match = str.match(/^(\d+(?:\.\d+)?)\s*([a-z]+)?$/);
|
|
76
|
+
if (!match) return defaultMs;
|
|
77
|
+
const num = parseFloat(match[1]);
|
|
78
|
+
const unit = match[2] || "d";
|
|
79
|
+
if (unit.startsWith("s")) return Math.round(num * 1e3);
|
|
80
|
+
if (unit.startsWith("m")) return Math.round(num * 60 * 1e3);
|
|
81
|
+
if (unit.startsWith("h")) return Math.round(num * 60 * 60 * 1e3);
|
|
82
|
+
if (unit.startsWith("d")) return Math.round(num * 24 * 60 * 60 * 1e3);
|
|
83
|
+
if (unit.startsWith("w")) return Math.round(num * 7 * 24 * 60 * 60 * 1e3);
|
|
84
|
+
return defaultMs;
|
|
85
|
+
}
|
|
86
|
+
function formatDurationTag(seconds) {
|
|
87
|
+
const s = Number(seconds) || 60;
|
|
88
|
+
if (s >= 2592e3 && s % 2592e3 === 0) return `${s / 2592e3}mo`;
|
|
89
|
+
if (s >= 604800 && s % 604800 === 0) return `${s / 604800}w`;
|
|
90
|
+
if (s >= 86400 && s % 86400 === 0) return `${s / 86400}d`;
|
|
91
|
+
if (s >= 3600 && s % 3600 === 0) return `${s / 3600}h`;
|
|
92
|
+
if (s >= 60 && s % 60 === 0) return `${s / 60}m`;
|
|
93
|
+
return `${s}s`;
|
|
94
|
+
}
|
|
95
|
+
function formatDurationLabel(seconds) {
|
|
96
|
+
const s = Number(seconds) || 60;
|
|
97
|
+
if (s === 60) return "1 \u043C\u0438\u043D";
|
|
98
|
+
if (s === 300) return "5 \u043C\u0438\u043D";
|
|
99
|
+
if (s === 600) return "10 \u043C\u0438\u043D";
|
|
100
|
+
if (s === 1800) return "30 \u043C\u0438\u043D";
|
|
101
|
+
if (s === 3600) return "1 \u0447\u0430\u0441";
|
|
102
|
+
if (s === 18e3) return "5 \u0447\u0430\u0441\u043E\u0432";
|
|
103
|
+
if (s === 43200) return "12 \u0447\u0430\u0441\u043E\u0432";
|
|
104
|
+
if (s === 86400) return "24 \u0447\u0430\u0441\u0430";
|
|
105
|
+
return formatDurationTag(s);
|
|
106
|
+
}
|
|
107
|
+
var duration_default = {
|
|
108
|
+
parseDurationToSeconds,
|
|
109
|
+
parseDurationMs,
|
|
110
|
+
formatDurationTag,
|
|
111
|
+
formatDurationLabel
|
|
112
|
+
};
|
|
113
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
114
|
+
0 && (module.exports = {
|
|
115
|
+
formatDurationLabel,
|
|
116
|
+
formatDurationTag,
|
|
117
|
+
parseDurationMs,
|
|
118
|
+
parseDurationToSeconds
|
|
119
|
+
});
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
var __create = Object.create;
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
20
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
21
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
22
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
23
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
24
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
25
|
+
mod
|
|
26
|
+
));
|
|
27
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
28
|
+
var oidc_exports = {};
|
|
29
|
+
__export(oidc_exports, {
|
|
30
|
+
buildAuthorizeUrl: () => buildAuthorizeUrl,
|
|
31
|
+
consumeState: () => consumeState,
|
|
32
|
+
decodeIdToken: () => decodeIdToken,
|
|
33
|
+
default: () => oidc_default,
|
|
34
|
+
discover: () => discover,
|
|
35
|
+
exchangeCode: () => exchangeCode,
|
|
36
|
+
generatePKCE: () => generatePKCE,
|
|
37
|
+
generateState: () => generateState,
|
|
38
|
+
getUserInfo: () => getUserInfo,
|
|
39
|
+
storeVerifier: () => storeVerifier
|
|
40
|
+
});
|
|
41
|
+
module.exports = __toCommonJS(oidc_exports);
|
|
42
|
+
var import_crypto = __toESM(require("crypto"), 1);
|
|
43
|
+
const DEFAULT_SECRET = typeof process !== "undefined" && (process.env?.OIDC_STATE_SECRET || process.env?.JWT_SECRET) || "cynx-oidc-state-secret-salt";
|
|
44
|
+
function generateState(payload = {}, secret = DEFAULT_SECRET) {
|
|
45
|
+
const data = Buffer.from(JSON.stringify({ ...payload, ts: Date.now() })).toString("base64url");
|
|
46
|
+
const sig = import_crypto.default.createHmac("sha256", secret).update(data).digest("base64url");
|
|
47
|
+
return `${data}.${sig}`;
|
|
48
|
+
}
|
|
49
|
+
function consumeState(stateStr, secret = DEFAULT_SECRET, ttlMs = 6e5) {
|
|
50
|
+
if (!stateStr || typeof stateStr !== "string") return null;
|
|
51
|
+
const parts = stateStr.split(".");
|
|
52
|
+
if (parts.length !== 2) return null;
|
|
53
|
+
const [data, sig] = parts;
|
|
54
|
+
const expectedSig = import_crypto.default.createHmac("sha256", secret).update(data).digest("base64url");
|
|
55
|
+
if (sig.length !== expectedSig.length) return null;
|
|
56
|
+
if (!import_crypto.default.timingSafeEqual(Buffer.from(sig), Buffer.from(expectedSig))) return null;
|
|
57
|
+
try {
|
|
58
|
+
const payload = JSON.parse(Buffer.from(data, "base64url").toString("utf8"));
|
|
59
|
+
if (!payload.ts || Date.now() - payload.ts > ttlMs) return null;
|
|
60
|
+
return payload;
|
|
61
|
+
} catch {
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
function generatePKCE() {
|
|
66
|
+
const codeVerifier = import_crypto.default.randomBytes(32).toString("base64url");
|
|
67
|
+
const codeChallenge = import_crypto.default.createHash("sha256").update(codeVerifier).digest("base64url");
|
|
68
|
+
return { codeVerifier, codeChallenge };
|
|
69
|
+
}
|
|
70
|
+
async function discover(issuer, discoveryPath = "/.well-known/openid-configuration") {
|
|
71
|
+
let base = issuer.replace(/\/+$/, "");
|
|
72
|
+
let path = discoveryPath || "/.well-known/openid-configuration";
|
|
73
|
+
if (base.endsWith(path)) {
|
|
74
|
+
base = base.slice(0, -path.length).replace(/\/+$/, "");
|
|
75
|
+
}
|
|
76
|
+
if (!path.startsWith("/")) path = "/" + path;
|
|
77
|
+
const url = base + path;
|
|
78
|
+
const res = await fetch(url);
|
|
79
|
+
if (!res.ok) throw new Error(`OIDC Discovery failed: ${res.status} \u2014 ${url}`);
|
|
80
|
+
return res.json();
|
|
81
|
+
}
|
|
82
|
+
function buildAuthorizeUrl(config, state, codeChallenge) {
|
|
83
|
+
const params = new URLSearchParams({
|
|
84
|
+
response_type: "code",
|
|
85
|
+
client_id: config.clientId,
|
|
86
|
+
redirect_uri: config.redirectUri,
|
|
87
|
+
scope: config.scopes || "openid profile email",
|
|
88
|
+
state
|
|
89
|
+
});
|
|
90
|
+
if (config.pkceEnabled !== false && codeChallenge) {
|
|
91
|
+
params.set("code_challenge", codeChallenge);
|
|
92
|
+
params.set("code_challenge_method", "S256");
|
|
93
|
+
}
|
|
94
|
+
const base = config.issuer.replace(/\/+$/, "");
|
|
95
|
+
return `${base}/authorize?${params.toString()}`;
|
|
96
|
+
}
|
|
97
|
+
async function exchangeCode(config, code, codeVerifier) {
|
|
98
|
+
const discoverDoc = await discover(config.issuer, config.discoveryPath);
|
|
99
|
+
const tokenUrl = discoverDoc.token_endpoint;
|
|
100
|
+
const body = new URLSearchParams({
|
|
101
|
+
grant_type: "authorization_code",
|
|
102
|
+
code,
|
|
103
|
+
redirect_uri: config.redirectUri,
|
|
104
|
+
client_id: config.clientId
|
|
105
|
+
});
|
|
106
|
+
if (config.clientSecret) {
|
|
107
|
+
body.set("client_secret", config.clientSecret);
|
|
108
|
+
}
|
|
109
|
+
if (config.pkceEnabled !== false && codeVerifier) {
|
|
110
|
+
body.set("code_verifier", codeVerifier);
|
|
111
|
+
}
|
|
112
|
+
const res = await fetch(tokenUrl, {
|
|
113
|
+
method: "POST",
|
|
114
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
115
|
+
body
|
|
116
|
+
});
|
|
117
|
+
if (!res.ok) {
|
|
118
|
+
const err = await res.text();
|
|
119
|
+
throw new Error(`Token exchange failed: ${res.status} ${err}`);
|
|
120
|
+
}
|
|
121
|
+
return res.json();
|
|
122
|
+
}
|
|
123
|
+
async function getUserInfo(config, accessToken) {
|
|
124
|
+
const discoverDoc = await discover(config.issuer, config.discoveryPath);
|
|
125
|
+
const userinfoUrl = discoverDoc.userinfo_endpoint;
|
|
126
|
+
if (!userinfoUrl) throw new Error("No userinfo_endpoint in discovery document");
|
|
127
|
+
const res = await fetch(userinfoUrl, {
|
|
128
|
+
headers: { Authorization: `Bearer ${accessToken}` }
|
|
129
|
+
});
|
|
130
|
+
if (!res.ok) throw new Error(`Userinfo failed: ${res.status}`);
|
|
131
|
+
return res.json();
|
|
132
|
+
}
|
|
133
|
+
function decodeIdToken(idToken) {
|
|
134
|
+
if (!idToken || typeof idToken !== "string") throw new Error("Invalid id_token");
|
|
135
|
+
const parts = idToken.split(".");
|
|
136
|
+
if (parts.length !== 3) throw new Error("Invalid id_token format (expected 3 parts)");
|
|
137
|
+
const payload = Buffer.from(parts[1], "base64url").toString("utf8");
|
|
138
|
+
return JSON.parse(payload);
|
|
139
|
+
}
|
|
140
|
+
function storeVerifier() {
|
|
141
|
+
}
|
|
142
|
+
var oidc_default = {
|
|
143
|
+
generateState,
|
|
144
|
+
storeVerifier,
|
|
145
|
+
consumeState,
|
|
146
|
+
generatePKCE,
|
|
147
|
+
discover,
|
|
148
|
+
buildAuthorizeUrl,
|
|
149
|
+
exchangeCode,
|
|
150
|
+
getUserInfo,
|
|
151
|
+
decodeIdToken
|
|
152
|
+
};
|
|
153
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
154
|
+
0 && (module.exports = {
|
|
155
|
+
buildAuthorizeUrl,
|
|
156
|
+
consumeState,
|
|
157
|
+
decodeIdToken,
|
|
158
|
+
discover,
|
|
159
|
+
exchangeCode,
|
|
160
|
+
generatePKCE,
|
|
161
|
+
generateState,
|
|
162
|
+
getUserInfo,
|
|
163
|
+
storeVerifier
|
|
164
|
+
});
|