@codenkay/video-nsgplayer-core 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -0
- package/dist/index.cjs +112 -19
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +23 -6
- package/dist/index.d.ts +23 -6
- package/dist/index.js +110 -19
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -239,14 +239,30 @@ type PlayerEventMap = {
|
|
|
239
239
|
};
|
|
240
240
|
|
|
241
241
|
declare const PLAYBACK_RATES: readonly [0.5, 0.75, 1, 1.25, 1.5, 2];
|
|
242
|
-
declare const PACKAGE_VERSION = "0.1.
|
|
242
|
+
declare const PACKAGE_VERSION = "0.1.2";
|
|
243
243
|
declare const DEFAULT_PLAYER_BEHAVIOR: Required<PlayerBehaviorConfig>;
|
|
244
244
|
declare const DEFAULT_CONTROLS: Required<ControlsConfig>;
|
|
245
245
|
declare const DEFAULT_THEME: Required<ThemeConfig>;
|
|
246
246
|
declare const DEFAULT_WATERMARK: Required<WatermarkConfig>;
|
|
247
247
|
declare const DEFAULT_PLAYER_CONFIG: PlayerConfig;
|
|
248
|
+
/** Hard cap so pathological graphs cannot blow the stack. */
|
|
249
|
+
declare const SECRET_SCAN_MAX_DEPTH = 32;
|
|
250
|
+
/**
|
|
251
|
+
* True only for JSON-like plain objects (`{}` / `Object.create(null)`).
|
|
252
|
+
* Excludes DOM nodes, class instances, arrays, dates, etc.
|
|
253
|
+
*/
|
|
254
|
+
declare function isPlainObject(value: unknown): value is Record<string, unknown>;
|
|
255
|
+
/**
|
|
256
|
+
* Scans plain config objects for forbidden secret key names.
|
|
257
|
+
*
|
|
258
|
+
* Enterprise guarantees:
|
|
259
|
+
* - Never deep-walks DOM / host / class instances (plain-object only)
|
|
260
|
+
* - Does not descend into `mount` / `auth` / `playback` (shallow key check only)
|
|
261
|
+
* - Cycle-safe via WeakSet
|
|
262
|
+
* - Depth-capped + iterative (no call-stack recursion)
|
|
263
|
+
*/
|
|
248
264
|
declare function assertNoSecretsInConfig(raw: unknown): void;
|
|
249
|
-
|
|
265
|
+
type PlayerConfigPartial = Partial<{
|
|
250
266
|
player: Partial<PlayerBehaviorConfig>;
|
|
251
267
|
controls: Partial<ControlsConfig>;
|
|
252
268
|
theme: Partial<ThemeConfig>;
|
|
@@ -259,7 +275,8 @@ declare function mergePlayerConfig(partial?: Partial<{
|
|
|
259
275
|
logging: Partial<PlayerConfig["logging"]>;
|
|
260
276
|
debug: Partial<PlayerConfig["debug"]>;
|
|
261
277
|
accessibility: Partial<PlayerConfig["accessibility"]>;
|
|
262
|
-
}
|
|
278
|
+
}>;
|
|
279
|
+
declare function mergePlayerConfig(partial?: PlayerConfigPartial): PlayerConfig;
|
|
263
280
|
/** Maps theme colors to CSS custom properties for UI adapters. */
|
|
264
281
|
declare function themeToCssVars(theme: Required<ThemeConfig>): Record<string, string>;
|
|
265
282
|
|
|
@@ -541,7 +558,7 @@ declare class RefreshManager {
|
|
|
541
558
|
private renew;
|
|
542
559
|
}
|
|
543
560
|
|
|
544
|
-
declare function redactValue(key: string, value: unknown): unknown;
|
|
545
|
-
declare function redactObject(obj: Record<string, unknown
|
|
561
|
+
declare function redactValue(key: string, value: unknown, seen?: WeakSet<object>, depth?: number): unknown;
|
|
562
|
+
declare function redactObject(obj: Record<string, unknown>, seen?: WeakSet<object>, depth?: number): Record<string, unknown>;
|
|
546
563
|
|
|
547
|
-
export { type AccessibilityConfig, type AnalyticsConfig, type AuthConfig, AuthManager, AuthParamsStore, type AuthToken, type AuthTokenProviderContext, type BufferedRange, type ControlsConfig, type CreateVideoPlayerOptions, DEFAULT_CONTROLS, DEFAULT_LIVE_EDGE_TOLERANCE_SECONDS, DEFAULT_PLAYER_BEHAVIOR, DEFAULT_PLAYER_CONFIG, DEFAULT_THEME, DEFAULT_WATERMARK, type DebugConfig, EventEmitter, type HlsQualityLevel, type HlsSupportMode, type LiveMediaSnapshot, type LoggingConfig, PACKAGE_VERSION, PLAYBACK_RATES, type PlayIconPreset, type PlaybackCredentialConfig, type PlaybackRate, type PlaybackSource, type PlaybackSourceContext, PlaybackSourceManager, type PlayerBehaviorConfig, type PlayerConfig, type PlayerDiagnostics, type PlayerError, PlayerErrorCode, type PlayerEventMap, type PlayerSkipSeconds, type PlayerState, type PlayerZoomLevel, type QualitySelection, RefreshManager, type SeekToLiveResult, type StreamingConfig, type ThemeConfig, type VideoPlayer, type WatermarkConfig, assertNoSecretsInConfig, createPlayerError, createVideoPlayer, getLiveEdgeTime, isAtLiveEdge, mergePlayerConfig, redactObject, redactSensitive, redactValue, seekToLiveEdge, themeToCssVars };
|
|
564
|
+
export { type AccessibilityConfig, type AnalyticsConfig, type AuthConfig, AuthManager, AuthParamsStore, type AuthToken, type AuthTokenProviderContext, type BufferedRange, type ControlsConfig, type CreateVideoPlayerOptions, DEFAULT_CONTROLS, DEFAULT_LIVE_EDGE_TOLERANCE_SECONDS, DEFAULT_PLAYER_BEHAVIOR, DEFAULT_PLAYER_CONFIG, DEFAULT_THEME, DEFAULT_WATERMARK, type DebugConfig, EventEmitter, type HlsQualityLevel, type HlsSupportMode, type LiveMediaSnapshot, type LoggingConfig, PACKAGE_VERSION, PLAYBACK_RATES, type PlayIconPreset, type PlaybackCredentialConfig, type PlaybackRate, type PlaybackSource, type PlaybackSourceContext, PlaybackSourceManager, type PlayerBehaviorConfig, type PlayerConfig, type PlayerDiagnostics, type PlayerError, PlayerErrorCode, type PlayerEventMap, type PlayerSkipSeconds, type PlayerState, type PlayerZoomLevel, type QualitySelection, RefreshManager, SECRET_SCAN_MAX_DEPTH, type SeekToLiveResult, type StreamingConfig, type ThemeConfig, type VideoPlayer, type WatermarkConfig, assertNoSecretsInConfig, createPlayerError, createVideoPlayer, getLiveEdgeTime, isAtLiveEdge, isPlainObject, mergePlayerConfig, redactObject, redactSensitive, redactValue, seekToLiveEdge, themeToCssVars };
|
package/dist/index.d.ts
CHANGED
|
@@ -239,14 +239,30 @@ type PlayerEventMap = {
|
|
|
239
239
|
};
|
|
240
240
|
|
|
241
241
|
declare const PLAYBACK_RATES: readonly [0.5, 0.75, 1, 1.25, 1.5, 2];
|
|
242
|
-
declare const PACKAGE_VERSION = "0.1.
|
|
242
|
+
declare const PACKAGE_VERSION = "0.1.2";
|
|
243
243
|
declare const DEFAULT_PLAYER_BEHAVIOR: Required<PlayerBehaviorConfig>;
|
|
244
244
|
declare const DEFAULT_CONTROLS: Required<ControlsConfig>;
|
|
245
245
|
declare const DEFAULT_THEME: Required<ThemeConfig>;
|
|
246
246
|
declare const DEFAULT_WATERMARK: Required<WatermarkConfig>;
|
|
247
247
|
declare const DEFAULT_PLAYER_CONFIG: PlayerConfig;
|
|
248
|
+
/** Hard cap so pathological graphs cannot blow the stack. */
|
|
249
|
+
declare const SECRET_SCAN_MAX_DEPTH = 32;
|
|
250
|
+
/**
|
|
251
|
+
* True only for JSON-like plain objects (`{}` / `Object.create(null)`).
|
|
252
|
+
* Excludes DOM nodes, class instances, arrays, dates, etc.
|
|
253
|
+
*/
|
|
254
|
+
declare function isPlainObject(value: unknown): value is Record<string, unknown>;
|
|
255
|
+
/**
|
|
256
|
+
* Scans plain config objects for forbidden secret key names.
|
|
257
|
+
*
|
|
258
|
+
* Enterprise guarantees:
|
|
259
|
+
* - Never deep-walks DOM / host / class instances (plain-object only)
|
|
260
|
+
* - Does not descend into `mount` / `auth` / `playback` (shallow key check only)
|
|
261
|
+
* - Cycle-safe via WeakSet
|
|
262
|
+
* - Depth-capped + iterative (no call-stack recursion)
|
|
263
|
+
*/
|
|
248
264
|
declare function assertNoSecretsInConfig(raw: unknown): void;
|
|
249
|
-
|
|
265
|
+
type PlayerConfigPartial = Partial<{
|
|
250
266
|
player: Partial<PlayerBehaviorConfig>;
|
|
251
267
|
controls: Partial<ControlsConfig>;
|
|
252
268
|
theme: Partial<ThemeConfig>;
|
|
@@ -259,7 +275,8 @@ declare function mergePlayerConfig(partial?: Partial<{
|
|
|
259
275
|
logging: Partial<PlayerConfig["logging"]>;
|
|
260
276
|
debug: Partial<PlayerConfig["debug"]>;
|
|
261
277
|
accessibility: Partial<PlayerConfig["accessibility"]>;
|
|
262
|
-
}
|
|
278
|
+
}>;
|
|
279
|
+
declare function mergePlayerConfig(partial?: PlayerConfigPartial): PlayerConfig;
|
|
263
280
|
/** Maps theme colors to CSS custom properties for UI adapters. */
|
|
264
281
|
declare function themeToCssVars(theme: Required<ThemeConfig>): Record<string, string>;
|
|
265
282
|
|
|
@@ -541,7 +558,7 @@ declare class RefreshManager {
|
|
|
541
558
|
private renew;
|
|
542
559
|
}
|
|
543
560
|
|
|
544
|
-
declare function redactValue(key: string, value: unknown): unknown;
|
|
545
|
-
declare function redactObject(obj: Record<string, unknown
|
|
561
|
+
declare function redactValue(key: string, value: unknown, seen?: WeakSet<object>, depth?: number): unknown;
|
|
562
|
+
declare function redactObject(obj: Record<string, unknown>, seen?: WeakSet<object>, depth?: number): Record<string, unknown>;
|
|
546
563
|
|
|
547
|
-
export { type AccessibilityConfig, type AnalyticsConfig, type AuthConfig, AuthManager, AuthParamsStore, type AuthToken, type AuthTokenProviderContext, type BufferedRange, type ControlsConfig, type CreateVideoPlayerOptions, DEFAULT_CONTROLS, DEFAULT_LIVE_EDGE_TOLERANCE_SECONDS, DEFAULT_PLAYER_BEHAVIOR, DEFAULT_PLAYER_CONFIG, DEFAULT_THEME, DEFAULT_WATERMARK, type DebugConfig, EventEmitter, type HlsQualityLevel, type HlsSupportMode, type LiveMediaSnapshot, type LoggingConfig, PACKAGE_VERSION, PLAYBACK_RATES, type PlayIconPreset, type PlaybackCredentialConfig, type PlaybackRate, type PlaybackSource, type PlaybackSourceContext, PlaybackSourceManager, type PlayerBehaviorConfig, type PlayerConfig, type PlayerDiagnostics, type PlayerError, PlayerErrorCode, type PlayerEventMap, type PlayerSkipSeconds, type PlayerState, type PlayerZoomLevel, type QualitySelection, RefreshManager, type SeekToLiveResult, type StreamingConfig, type ThemeConfig, type VideoPlayer, type WatermarkConfig, assertNoSecretsInConfig, createPlayerError, createVideoPlayer, getLiveEdgeTime, isAtLiveEdge, mergePlayerConfig, redactObject, redactSensitive, redactValue, seekToLiveEdge, themeToCssVars };
|
|
564
|
+
export { type AccessibilityConfig, type AnalyticsConfig, type AuthConfig, AuthManager, AuthParamsStore, type AuthToken, type AuthTokenProviderContext, type BufferedRange, type ControlsConfig, type CreateVideoPlayerOptions, DEFAULT_CONTROLS, DEFAULT_LIVE_EDGE_TOLERANCE_SECONDS, DEFAULT_PLAYER_BEHAVIOR, DEFAULT_PLAYER_CONFIG, DEFAULT_THEME, DEFAULT_WATERMARK, type DebugConfig, EventEmitter, type HlsQualityLevel, type HlsSupportMode, type LiveMediaSnapshot, type LoggingConfig, PACKAGE_VERSION, PLAYBACK_RATES, type PlayIconPreset, type PlaybackCredentialConfig, type PlaybackRate, type PlaybackSource, type PlaybackSourceContext, PlaybackSourceManager, type PlayerBehaviorConfig, type PlayerConfig, type PlayerDiagnostics, type PlayerError, PlayerErrorCode, type PlayerEventMap, type PlayerSkipSeconds, type PlayerState, type PlayerZoomLevel, type QualitySelection, RefreshManager, SECRET_SCAN_MAX_DEPTH, type SeekToLiveResult, type StreamingConfig, type ThemeConfig, type VideoPlayer, type WatermarkConfig, assertNoSecretsInConfig, createPlayerError, createVideoPlayer, getLiveEdgeTime, isAtLiveEdge, isPlainObject, mergePlayerConfig, redactObject, redactSensitive, redactValue, seekToLiveEdge, themeToCssVars };
|
package/dist/index.js
CHANGED
|
@@ -146,7 +146,7 @@ var AuthManager = class {
|
|
|
146
146
|
|
|
147
147
|
// src/config/defaults.ts
|
|
148
148
|
var PLAYBACK_RATES = [0.5, 0.75, 1, 1.25, 1.5, 2];
|
|
149
|
-
var PACKAGE_VERSION = "0.1.
|
|
149
|
+
var PACKAGE_VERSION = "0.1.2";
|
|
150
150
|
var DEFAULT_PLAYER_BEHAVIOR = {
|
|
151
151
|
autoplay: true,
|
|
152
152
|
startMuted: true,
|
|
@@ -232,22 +232,83 @@ var FORBIDDEN_SECRET_KEYS = [
|
|
|
232
232
|
"basicauthpassword",
|
|
233
233
|
"password"
|
|
234
234
|
];
|
|
235
|
+
var SKIP_DEEP_SCAN_KEYS = /* @__PURE__ */ new Set([
|
|
236
|
+
"mount",
|
|
237
|
+
"auth",
|
|
238
|
+
"playback",
|
|
239
|
+
"gettoken",
|
|
240
|
+
"getsource",
|
|
241
|
+
"refreshsource",
|
|
242
|
+
"keyproxyurlbuilder"
|
|
243
|
+
]);
|
|
244
|
+
var SECRET_SCAN_MAX_DEPTH = 32;
|
|
245
|
+
function isPlainObject(value) {
|
|
246
|
+
if (value === null || typeof value !== "object") return false;
|
|
247
|
+
if (Array.isArray(value)) return false;
|
|
248
|
+
const proto = Object.getPrototypeOf(value);
|
|
249
|
+
return proto === Object.prototype || proto === null;
|
|
250
|
+
}
|
|
251
|
+
function normalizeConfigKey(key) {
|
|
252
|
+
return key.toLowerCase().replace(/[^a-z0-9]/g, "");
|
|
253
|
+
}
|
|
254
|
+
function isForbiddenSecretKey(key) {
|
|
255
|
+
const lower = normalizeConfigKey(key);
|
|
256
|
+
return FORBIDDEN_SECRET_KEYS.some((k) => lower.includes(k));
|
|
257
|
+
}
|
|
258
|
+
function throwForbidden(path, key) {
|
|
259
|
+
throw new Error(
|
|
260
|
+
`INVALID_CONFIGURATION: Forbidden secret key "${path}${key}" must never be passed to the browser SDK. Keep clientSecret on your server/BFF and use auth.getToken().`
|
|
261
|
+
);
|
|
262
|
+
}
|
|
235
263
|
function assertNoSecretsInConfig(raw) {
|
|
236
|
-
if (!raw
|
|
237
|
-
const
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
264
|
+
if (!isPlainObject(raw) && !Array.isArray(raw)) return;
|
|
265
|
+
const seen = /* @__PURE__ */ new WeakSet();
|
|
266
|
+
const stack = [
|
|
267
|
+
{ value: raw, path: "", depth: 0 }
|
|
268
|
+
];
|
|
269
|
+
while (stack.length > 0) {
|
|
270
|
+
const current = stack.pop();
|
|
271
|
+
if (current.depth > SECRET_SCAN_MAX_DEPTH) continue;
|
|
272
|
+
const { value, path, depth } = current;
|
|
273
|
+
if (Array.isArray(value)) {
|
|
274
|
+
if (seen.has(value)) continue;
|
|
275
|
+
seen.add(value);
|
|
276
|
+
for (let i = 0; i < value.length; i += 1) {
|
|
277
|
+
const item = value[i];
|
|
278
|
+
if (isPlainObject(item) || Array.isArray(item)) {
|
|
279
|
+
stack.push({ value: item, path: `${path}[${i}]`, depth: depth + 1 });
|
|
280
|
+
}
|
|
244
281
|
}
|
|
245
|
-
|
|
246
|
-
|
|
282
|
+
continue;
|
|
283
|
+
}
|
|
284
|
+
if (!isPlainObject(value)) continue;
|
|
285
|
+
if (seen.has(value)) continue;
|
|
286
|
+
seen.add(value);
|
|
287
|
+
for (const [key, child] of Object.entries(value)) {
|
|
288
|
+
const normalized = normalizeConfigKey(key);
|
|
289
|
+
if (isForbiddenSecretKey(key)) {
|
|
290
|
+
throwForbidden(path, key);
|
|
291
|
+
}
|
|
292
|
+
if (normalized === "mount") continue;
|
|
293
|
+
if (SKIP_DEEP_SCAN_KEYS.has(normalized)) {
|
|
294
|
+
if (isPlainObject(child)) {
|
|
295
|
+
for (const nestedKey of Object.keys(child)) {
|
|
296
|
+
if (isForbiddenSecretKey(nestedKey)) {
|
|
297
|
+
throwForbidden(`${path}${key}.`, nestedKey);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
continue;
|
|
302
|
+
}
|
|
303
|
+
if (isPlainObject(child) || Array.isArray(child)) {
|
|
304
|
+
stack.push({
|
|
305
|
+
value: child,
|
|
306
|
+
path: path ? `${path}${key}.` : `${key}.`,
|
|
307
|
+
depth: depth + 1
|
|
308
|
+
});
|
|
247
309
|
}
|
|
248
310
|
}
|
|
249
|
-
}
|
|
250
|
-
walk(raw, "");
|
|
311
|
+
}
|
|
251
312
|
}
|
|
252
313
|
function mergePlayerConfig(partial) {
|
|
253
314
|
assertNoSecretsInConfig(partial);
|
|
@@ -335,7 +396,14 @@ var EventEmitter = class {
|
|
|
335
396
|
|
|
336
397
|
// src/security/redaction.ts
|
|
337
398
|
var SENSITIVE_KEYS = /^(authorization|cookie|set-cookie|x-api-key|token|accessToken|access_token|clientSecret|password)$/i;
|
|
338
|
-
|
|
399
|
+
var REDACT_MAX_DEPTH = 32;
|
|
400
|
+
function isPlainObject2(value) {
|
|
401
|
+
if (value === null || typeof value !== "object") return false;
|
|
402
|
+
if (Array.isArray(value)) return false;
|
|
403
|
+
const proto = Object.getPrototypeOf(value);
|
|
404
|
+
return proto === Object.prototype || proto === null;
|
|
405
|
+
}
|
|
406
|
+
function redactValue(key, value, seen = /* @__PURE__ */ new WeakSet(), depth = 0) {
|
|
339
407
|
if (SENSITIVE_KEYS.test(key)) return "[REDACTED]";
|
|
340
408
|
if (typeof value === "string") {
|
|
341
409
|
if (/^https?:\/\//i.test(value) && /[?&](token|expires)=/i.test(value)) {
|
|
@@ -352,15 +420,25 @@ function redactValue(key, value) {
|
|
|
352
420
|
}
|
|
353
421
|
}
|
|
354
422
|
}
|
|
355
|
-
if (
|
|
356
|
-
|
|
423
|
+
if (Array.isArray(value)) {
|
|
424
|
+
if (depth >= REDACT_MAX_DEPTH || seen.has(value)) return "[REDACTED_CYCLE]";
|
|
425
|
+
seen.add(value);
|
|
426
|
+
return value.map(
|
|
427
|
+
(item, index) => redactValue(String(index), item, seen, depth + 1)
|
|
428
|
+
);
|
|
429
|
+
}
|
|
430
|
+
if (isPlainObject2(value)) {
|
|
431
|
+
return redactObject(value, seen, depth + 1);
|
|
357
432
|
}
|
|
358
433
|
return value;
|
|
359
434
|
}
|
|
360
|
-
function redactObject(obj) {
|
|
435
|
+
function redactObject(obj, seen = /* @__PURE__ */ new WeakSet(), depth = 0) {
|
|
436
|
+
if (depth > REDACT_MAX_DEPTH) return { "[REDACTED]": "max_depth" };
|
|
437
|
+
if (seen.has(obj)) return { "[REDACTED]": "cycle" };
|
|
438
|
+
seen.add(obj);
|
|
361
439
|
const out = {};
|
|
362
440
|
for (const [key, value] of Object.entries(obj)) {
|
|
363
|
-
out[key] = redactValue(key, value);
|
|
441
|
+
out[key] = redactValue(key, value, seen, depth);
|
|
364
442
|
}
|
|
365
443
|
return out;
|
|
366
444
|
}
|
|
@@ -830,7 +908,18 @@ function generateSessionId() {
|
|
|
830
908
|
return `ps_${Date.now()}_${Math.random().toString(36).slice(2, 10)}`;
|
|
831
909
|
}
|
|
832
910
|
function createVideoPlayer(options) {
|
|
833
|
-
assertNoSecretsInConfig(
|
|
911
|
+
assertNoSecretsInConfig({
|
|
912
|
+
videoId: options.videoId,
|
|
913
|
+
sourceUrl: options.sourceUrl,
|
|
914
|
+
player: options.player,
|
|
915
|
+
controls: options.controls,
|
|
916
|
+
theme: options.theme,
|
|
917
|
+
watermark: options.watermark,
|
|
918
|
+
streaming: options.streaming,
|
|
919
|
+
logging: options.logging,
|
|
920
|
+
debug: options.debug,
|
|
921
|
+
accessibility: options.accessibility
|
|
922
|
+
});
|
|
834
923
|
let config = mergePlayerConfig({
|
|
835
924
|
player: options.player,
|
|
836
925
|
controls: options.controls,
|
|
@@ -1212,11 +1301,13 @@ export {
|
|
|
1212
1301
|
PlaybackSourceManager,
|
|
1213
1302
|
PlayerErrorCode,
|
|
1214
1303
|
RefreshManager,
|
|
1304
|
+
SECRET_SCAN_MAX_DEPTH,
|
|
1215
1305
|
assertNoSecretsInConfig,
|
|
1216
1306
|
createPlayerError,
|
|
1217
1307
|
createVideoPlayer,
|
|
1218
1308
|
getLiveEdgeTime,
|
|
1219
1309
|
isAtLiveEdge,
|
|
1310
|
+
isPlainObject,
|
|
1220
1311
|
mergePlayerConfig,
|
|
1221
1312
|
redactObject,
|
|
1222
1313
|
redactSensitive,
|