@xnstream/player-sdk
Version:
XStream Player SDK - A powerful video player SDK for streaming content
140 lines • 5.4 kB
JavaScript
import { LocalStorageSecureStorage } from './SecureStorage';
import { UAParser } from 'ua-parser-js';
import { generateSignature, generateRandomSalt, base64Encode, decryptAESWithCryptoJS, } from '../utils/crypto';
export class SessionRegistration {
constructor(appId, storage) {
this.SESSION_KEY = 'xplayer_session_id';
this.SECRET_KEY = 'xplayer_secret_key';
this.aps = undefined;
this.appId = appId;
this.storage = storage;
}
static async create(appId) {
const storage = await LocalStorageSecureStorage.create();
return new SessionRegistration(appId, storage);
}
async generateDeviceInfo() {
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
const uap = await UAParser().withFeatureCheck();
return {
user_agent: uap.ua,
ua_client_type: 'browser',
ua_client_name: (_a = uap.browser.name) !== null && _a !== void 0 ? _a : 'N/A',
ua_client_version: (_b = uap.browser.version) !== null && _b !== void 0 ? _b : 'N/A',
ua_client_engine: (_c = uap.engine.name) !== null && _c !== void 0 ? _c : 'N/A',
ua_client_engine_version: (_d = uap.engine.version) !== null && _d !== void 0 ? _d : 'N/A',
ua_device_type: (_e = uap.device.type) !== null && _e !== void 0 ? _e : 'desktop',
ua_device_brand: (_f = uap.device.vendor) !== null && _f !== void 0 ? _f : 'unknown',
ua_device_model: (_g = uap.device.model) !== null && _g !== void 0 ? _g : 'unknown',
ua_os_name: (_h = uap.os.name) !== null && _h !== void 0 ? _h : 'unknown',
ua_os_version: (_j = uap.os.version) !== null && _j !== void 0 ? _j : 'unknown',
};
}
async getDeviceInfo() {
return this.generateDeviceInfo();
}
getAppId() {
return this.appId;
}
getAps() {
return this.aps;
}
async setAps() {
this.aps = await this.storage.get(this.SECRET_KEY);
return;
}
/**
* Register device with the server (POST /player/register)
*/
async registerWithServer(resourceCode, baseUrl) {
const nce = generateRandomSalt();
const at = Math.floor(Date.now() / 1000);
const message = [this.appId, nce, at, resourceCode].join('|');
const sig = base64Encode(generateSignature(message, this.appId));
const body = {
device: await this.getDeviceInfo(),
app_id: this.appId,
nce,
at,
rs: resourceCode,
sig,
};
const response = await fetch(`${baseUrl}/player/app/register`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(body),
});
if (!response.ok) {
throw new Error('Device registration failed');
}
const result = (await response.json());
// Decrypt app secret
const decrypted = decryptAESWithCryptoJS(result.aps, this.appId);
// Store session ID and decrypted app secret securely
await this.storage.set(this.SESSION_KEY, result.sid);
await this.storage.set(this.SECRET_KEY, decrypted);
this.aps = decrypted;
return result;
}
/**
* Refresh session (POST /player/sid/refresh)
*/
async refreshSession(resourceCode, baseUrl, sessionId) {
const nce = generateRandomSalt();
const at = Math.floor(Date.now() / 1000);
const message = [this.appId, nce, at, resourceCode].join('|');
const sig = base64Encode(generateSignature(message, sessionId));
const body = {
device: await this.getDeviceInfo(),
app_id: this.appId,
sid: sessionId,
nce,
at,
rs: resourceCode,
sig,
};
const response = await fetch(`${baseUrl}/player/sid/refresh`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(body),
});
if (!response.ok) {
throw new Error('Session refresh failed');
}
const result = (await response.json());
await this.storage.set(this.SESSION_KEY, result.sid);
return result;
}
/**
* Fetch resource details from the server (POST /player/resource)
*/
async fetchResource(resourceCode, baseUrl) {
var _a;
const req = {
app_id: this.appId,
sid: await this.storage.get(this.SESSION_KEY),
rs: resourceCode,
};
const response = await fetch(`${baseUrl}/player/resource`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(req),
});
if (!response.ok) {
const resp = await this.refreshSession(resourceCode, baseUrl, (_a = req.sid) !== null && _a !== void 0 ? _a : '');
return Promise.resolve(resp);
}
return response.json();
}
/**
* Get the current session ID from storage
*/
async getSession() {
return this.storage.get(this.SESSION_KEY);
}
async unregister() {
await this.storage.remove(this.SESSION_KEY);
await this.storage.remove(this.SECRET_KEY);
}
}
//# sourceMappingURL=SessionRegistration.js.map