feat(integrations): add synology photos support

This commit is contained in:
Marek Maslowski
2026-04-03 02:58:22 +02:00
parent 8e9f8784dc
commit 78a91ccb95
7 changed files with 700 additions and 3 deletions
+59
View File
@@ -632,6 +632,65 @@ function runMigrations(db: Database.Database): void {
}
}
},
() => {
// Add Synology credential columns for existing databases
try { db.exec('ALTER TABLE users ADD COLUMN synology_url TEXT'); } catch (err: any) { if (!err.message?.includes('duplicate column name')) throw err; }
try { db.exec('ALTER TABLE users ADD COLUMN synology_username TEXT'); } catch (err: any) { if (!err.message?.includes('duplicate column name')) throw err; }
try { db.exec('ALTER TABLE users ADD COLUMN synology_password TEXT'); } catch (err: any) { if (!err.message?.includes('duplicate column name')) throw err; }
try { db.exec('ALTER TABLE users ADD COLUMN synology_sid TEXT'); } catch (err: any) { if (!err.message?.includes('duplicate column name')) throw err; }
},
() => {
// Seed Synology Photos provider and fields in existing databases
try {
db.prepare(`
INSERT INTO photo_providers (id, name, description, icon, enabled, config, sort_order)
VALUES (?, ?, ?, ?, ?, ?, ?)
ON CONFLICT(id) DO UPDATE SET
name = excluded.name,
description = excluded.description,
icon = excluded.icon,
enabled = excluded.enabled,
config = excluded.config,
sort_order = excluded.sort_order
`).run(
'synologyphotos',
'Synology Photos',
'Synology Photos integration with separate account settings',
'Image',
0,
JSON.stringify({
settings_get: '/integrations/synologyphotos/settings',
settings_put: '/integrations/synologyphotos/settings',
status_get: '/integrations/synologyphotos/status',
test_get: '/integrations/synologyphotos/status',
}),
1,
);
} catch (err: any) {
if (!err.message?.includes('no such table')) throw err;
}
try {
const insertField = db.prepare(`
INSERT INTO photo_provider_fields
(provider_id, field_key, label, input_type, placeholder, required, secret, settings_key, payload_key, sort_order)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
ON CONFLICT(provider_id, field_key) DO UPDATE SET
label = excluded.label,
input_type = excluded.input_type,
placeholder = excluded.placeholder,
required = excluded.required,
secret = excluded.secret,
settings_key = excluded.settings_key,
payload_key = excluded.payload_key,
sort_order = excluded.sort_order
`);
insertField.run('synologyphotos', 'synology_url', 'Server URL', 'url', 'https://synology.example.com', 1, 0, 'synology_url', 'synology_url', 0);
insertField.run('synologyphotos', 'synology_username', 'Username', 'text', 'Username', 1, 0, 'synology_username', 'synology_username', 1);
insertField.run('synologyphotos', 'synology_password', 'Password', 'password', 'Password', 1, 1, null, 'synology_password', 2);
} catch (err: any) {
if (!err.message?.includes('no such table')) throw err;
}
},
];
if (currentVersion < migrations.length) {
+4
View File
@@ -18,6 +18,10 @@ function createTables(db: Database.Database): void {
mfa_enabled INTEGER DEFAULT 0,
mfa_secret TEXT,
mfa_backup_codes TEXT,
synology_url TEXT,
synology_username TEXT,
synology_password TEXT,
synology_sid TEXT,
must_change_password INTEGER DEFAULT 0,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
+17
View File
@@ -108,6 +108,20 @@ function seedAddons(db: Database.Database): void {
test_post: '/integrations/immich/test',
}),
},
{
id: 'synologyphotos',
name: 'Synology Photos',
description: 'Synology Photos integration with separate account settings',
icon: 'Image',
enabled: 0,
sort_order: 1,
config: JSON.stringify({
settings_get: '/integrations/synologyphotos/settings',
settings_put: '/integrations/synologyphotos/settings',
status_get: '/integrations/synologyphotos/status',
test_get: '/integrations/synologyphotos/status',
}),
},
];
const insertProvider = db.prepare('INSERT OR IGNORE INTO photo_providers (id, name, description, icon, enabled, config, sort_order) VALUES (?, ?, ?, ?, ?, ?, ?)');
for (const p of providerRows) insertProvider.run(p.id, p.name, p.description, p.icon, p.enabled, p.config, p.sort_order);
@@ -115,6 +129,9 @@ function seedAddons(db: Database.Database): void {
const providerFields = [
{ provider_id: 'immich', field_key: 'immich_url', label: 'Immich URL', input_type: 'url', placeholder: 'https://immich.example.com', required: 1, secret: 0, settings_key: 'immich_url', payload_key: 'immich_url', sort_order: 0 },
{ provider_id: 'immich', field_key: 'immich_api_key', label: 'API Key', input_type: 'password', placeholder: 'API Key', required: 1, secret: 1, settings_key: null, payload_key: 'immich_api_key', sort_order: 1 },
{ provider_id: 'synologyphotos', field_key: 'synology_url', label: 'Server URL', input_type: 'url', placeholder: 'https://synology.example.com', required: 1, secret: 0, settings_key: 'synology_url', payload_key: 'synology_url', sort_order: 0 },
{ provider_id: 'synologyphotos', field_key: 'synology_username', label: 'Username', input_type: 'text', placeholder: 'Username', required: 1, secret: 0, settings_key: 'synology_username', payload_key: 'synology_username', sort_order: 1 },
{ provider_id: 'synologyphotos', field_key: 'synology_password', label: 'Password', input_type: 'password', placeholder: 'Password', required: 1, secret: 1, settings_key: null, payload_key: 'synology_password', sort_order: 2 },
];
const insertProviderField = db.prepare('INSERT OR IGNORE INTO photo_provider_fields (provider_id, field_key, label, input_type, placeholder, required, secret, settings_key, payload_key, sort_order) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)');
for (const f of providerFields) {