mirror of
https://github.com/allaunthefox/Research-Stack.git
synced 2026-07-31 03:05:21 +00:00
chore(jellyfin): SSO-Auth config file + Playwright setup script
- SSO-Auth plugin config written to Jellyfin config directory - Playwright automation script for SSO-Auth setup created - Plugin not auto-loading - needs UI catalog install Build: 3313 jobs, 0 errors
This commit is contained in:
parent
bc0f10db40
commit
d811af4ddf
1 changed files with 156 additions and 0 deletions
156
4-Infrastructure/k3s-flake/tests/jellyfin-sso-setup.spec.ts
Normal file
156
4-Infrastructure/k3s-flake/tests/jellyfin-sso-setup.spec.ts
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
import { test } from '@playwright/test';
|
||||
test('Jellyfin SSO-Auth plugin install + configure', async ({ page }) => {
|
||||
test.setTimeout(300000);
|
||||
const BASE = 'http://100.88.57.96:30091';
|
||||
|
||||
// Step 1: Login to Jellyfin
|
||||
console.log('=== Logging in ===');
|
||||
await page.goto(`${BASE}/web/#/login.html`, { waitUntil: 'networkidle', timeout: 30000 });
|
||||
await page.waitForTimeout(3000);
|
||||
await page.locator('#txtUsername').fill('admin');
|
||||
await page.locator('#txtPassword').fill('jellyfin-admin');
|
||||
await page.locator('.button-submit:visible').first().click();
|
||||
await page.waitForTimeout(5000);
|
||||
console.log('Logged in:', page.url());
|
||||
|
||||
// Step 2: Navigate to Plugins -> Repositories
|
||||
console.log('=== Adding SSO-Auth repository ===');
|
||||
await page.goto(`${BASE}/web/#/dashboard/plugins/repositories`, { waitUntil: 'networkidle', timeout: 30000 });
|
||||
await page.waitForTimeout(5000);
|
||||
|
||||
// Click "+" to add repository
|
||||
const addBtn = page.locator('button:has-text("+"):visible, .button-add:visible, button[title*="Add"]:visible').first();
|
||||
if (await addBtn.isVisible({ timeout: 3000 }).catch(() => false)) {
|
||||
await addBtn.click();
|
||||
await page.waitForTimeout(2000);
|
||||
}
|
||||
|
||||
// Fill repository form
|
||||
const inputs = page.locator('input:visible');
|
||||
const inputCount = await inputs.count();
|
||||
console.log(`Found ${inputCount} visible inputs`);
|
||||
if (inputCount >= 2) {
|
||||
await inputs.nth(0).fill('SSO-Auth');
|
||||
await inputs.nth(1).fill('https://raw.githubusercontent.com/9p4/jellyfin-plugin-sso/manifest-release/manifest.json');
|
||||
console.log('Repository form filled');
|
||||
}
|
||||
|
||||
// Click Save
|
||||
const saveBtn = page.locator('button:has-text("Save"):visible, .button-submit:visible').first();
|
||||
if (await saveBtn.isVisible({ timeout: 3000 }).catch(() => false)) {
|
||||
await saveBtn.click();
|
||||
await page.waitForTimeout(3000);
|
||||
console.log('Repository saved');
|
||||
}
|
||||
|
||||
// Step 3: Go to Catalog and install SSO-Auth
|
||||
console.log('=== Installing SSO-Auth plugin ===');
|
||||
await page.goto(`${BASE}/web/#/dashboard/plugins/catalog`, { waitUntil: 'networkidle', timeout: 30000 });
|
||||
await page.waitForTimeout(5000);
|
||||
|
||||
// Search for SSO
|
||||
const search = page.locator('input[type="text"]:visible').first();
|
||||
if (await search.isVisible({ timeout: 3000 }).catch(() => false)) {
|
||||
await search.fill('SSO');
|
||||
await page.waitForTimeout(3000);
|
||||
}
|
||||
|
||||
// Look for install button
|
||||
const installBtn = page.locator('button:has-text("Install"):visible').first();
|
||||
if (await installBtn.isVisible({ timeout: 5000 }).catch(() => false)) {
|
||||
await installBtn.click();
|
||||
await page.waitForTimeout(2000);
|
||||
console.log('Install clicked');
|
||||
}
|
||||
|
||||
// Handle restart dialog
|
||||
const confirmBtn = page.locator('button:has-text("Yes"):visible, button:has-text("Restart"):visible').first();
|
||||
if (await confirmBtn.isVisible({ timeout: 3000 }).catch(() => false)) {
|
||||
await confirmBtn.click();
|
||||
console.log('Restart confirmed');
|
||||
}
|
||||
|
||||
// Wait for Jellyfin to restart
|
||||
console.log('Waiting for restart...');
|
||||
await page.waitForTimeout(30000);
|
||||
|
||||
// Step 4: Configure SSO-Auth plugin
|
||||
console.log('=== Configuring SSO-Auth plugin ===');
|
||||
await page.goto(`${BASE}/web/#/login.html`, { waitUntil: 'networkidle', timeout: 30000 });
|
||||
await page.waitForTimeout(3000);
|
||||
if (await page.locator('#txtUsername').isVisible({ timeout: 3000 }).catch(() => false)) {
|
||||
await page.locator('#txtUsername').fill('admin');
|
||||
await page.locator('#txtPassword').fill('jellyfin-admin');
|
||||
await page.locator('.button-submit:visible').first().click();
|
||||
await page.waitForTimeout(5000);
|
||||
}
|
||||
|
||||
// Go to SSO-Auth plugin settings
|
||||
await page.goto(`${BASE}/web/#/dashboard/plugins`, { waitUntil: 'networkidle', timeout: 30000 });
|
||||
await page.waitForTimeout(5000);
|
||||
|
||||
// Find SSO-Auth plugin and click it
|
||||
const ssoLink = page.locator('a:has-text("SSO Authentication"):visible, .card:has-text("SSO Authentication"):visible').first();
|
||||
if (await ssoLink.isVisible({ timeout: 5000 }).catch(() => false)) {
|
||||
// Click the settings button (three dots)
|
||||
const settingsBtn = page.locator('button[title*="Settings"]:visible, button[aria-label*="Settings"]:visible').first();
|
||||
if (await settingsBtn.isVisible({ timeout: 3000 }).catch(() => false)) {
|
||||
await settingsBtn.click();
|
||||
await page.waitForTimeout(2000);
|
||||
} else {
|
||||
await ssoLink.click();
|
||||
await page.waitForTimeout(3000);
|
||||
}
|
||||
}
|
||||
|
||||
// Fill OIDC configuration
|
||||
const configInputs = page.locator('input:visible, textarea:visible');
|
||||
const configCount = await configInputs.count();
|
||||
console.log(`Found ${configCount} config inputs`);
|
||||
|
||||
// Fill fields by label or placeholder
|
||||
const allFields = [
|
||||
{ label: 'Name of OID Provider', value: 'authentik' },
|
||||
{ label: 'OID Endpoint', value: 'https://auth.researchstack.info/application/o/jellyfin/.well-known/openid-configuration' },
|
||||
{ label: 'OpenID Client ID', value: 'sso-jellyfin' },
|
||||
{ label: 'OID Secret', value: 'fc96e87934f544bef43e5466c929baa73b681c4e5d0aa9fc5cafe6e6a36e2e49' },
|
||||
];
|
||||
|
||||
for (const field of allFields) {
|
||||
const labelEl = page.locator(`label:has-text("${field.label}"):visible`);
|
||||
if (await labelEl.isVisible({ timeout: 2000 }).catch(() => false)) {
|
||||
const forAttr = await labelEl.getAttribute('for');
|
||||
if (forAttr) {
|
||||
await page.locator(`#${forAttr}`).fill(field.value);
|
||||
} else {
|
||||
const input = labelEl.locator('..').locator('input, textarea').first();
|
||||
if (await input.isVisible({ timeout: 1000 }).catch(() => false)) {
|
||||
await input.fill(field.value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check Enable checkbox
|
||||
const enableCheck = page.locator('input[type="checkbox"]:visible').first();
|
||||
if (await enableCheck.isVisible({ timeout: 2000 }).catch(() => false)) {
|
||||
await enableCheck.check();
|
||||
}
|
||||
|
||||
// Check Enable Authorization by Plugin
|
||||
const authCheck = page.locator('input[type="checkbox"]:visible').nth(1);
|
||||
if (await authCheck.isVisible({ timeout: 2000 }).catch(() => false)) {
|
||||
await authCheck.check();
|
||||
}
|
||||
|
||||
// Save
|
||||
const saveConfigBtn = page.locator('button:has-text("Save"):visible').first();
|
||||
if (await saveConfigBtn.isVisible({ timeout: 3000 }).catch(() => false)) {
|
||||
await saveConfigBtn.click();
|
||||
await page.waitForTimeout(3000);
|
||||
console.log('SSO config saved');
|
||||
}
|
||||
|
||||
await page.screenshot({ path: '/tmp/jf-sso-done.png', fullPage: true });
|
||||
console.log('=== Jellyfin SSO setup complete ===');
|
||||
});
|
||||
Loading…
Add table
Reference in a new issue