Files
cloudron-box/src/applinks.js
T

131 lines
4.4 KiB
JavaScript
Raw Normal View History

2022-07-06 19:15:59 +02:00
'use strict';
exports = module.exports = {
list,
add,
get,
update,
2022-07-07 14:11:14 +02:00
remove,
getIcon
2022-07-06 19:15:59 +02:00
};
const assert = require('assert'),
database = require('./database.js'),
BoxError = require('./boxerror.js'),
uuid = require('uuid'),
safe = require('safetydance'),
superagent = require('superagent'),
jsdom = require('jsdom'),
2022-07-06 19:15:59 +02:00
debug = require('debug')('box:applinks');
const APPLINKS_FIELDS= [ 'id', 'accessRestrictionJson', 'creationTime', 'updateTime', 'ts', 'label', 'tagsJson', 'icon', 'upstreamUri' ].join(',');
function postProcess(result) {
assert.strictEqual(typeof result, 'object');
assert(result.tagsJson === null || typeof result.tagsJson === 'string');
result.tags = safe.JSON.parse(result.tagsJson) || [];
delete result.tagsJson;
assert(result.accessRestrictionJson === null || typeof result.accessRestrictionJson === 'string');
result.accessRestriction = safe.JSON.parse(result.accessRestrictionJson);
if (result.accessRestriction && !result.accessRestriction.users) result.accessRestriction.users = [];
delete result.accessRestrictionJson;
2022-07-07 14:11:14 +02:00
result.icon = result.icon ? result.icon : null;
2022-07-06 19:15:59 +02:00
}
async function list() {
debug('list');
const results = await database.query(`SELECT ${APPLINKS_FIELDS} FROM applinks ORDER BY upstreamUri`);
results.forEach(postProcess);
return results;
}
async function add(applink) {
assert.strictEqual(typeof applink, 'object');
assert.strictEqual(typeof applink.upstreamUri, 'string');
debug(`add: ${applink.upstreamUri}`, applink);
// TODO applink property validation and fetch icon and label if not provided
if (!applink.icon) {
const [error, response] = await safe(superagent.get(applink.upstreamUri));
if (error || !response.text) throw new BoxError(BoxError.BAD_FIELD, 'cannot fetch applink icon');
const dom = new jsdom.JSDOM(response.text);
if (dom.window.document.querySelector('link[rel="icon"]')) {
const favicon = dom.window.document.querySelector('link[rel="icon"]').href ;
const [error, response] = await safe(superagent.get(favicon));
2022-07-07 14:11:14 +02:00
if (error) throw new BoxError(BoxError.BAD_FIELD, 'cannot fetch applink icon');
2022-07-07 14:11:14 +02:00
if (response.ok && response.headers['content-type'] === 'image/png') applink.icon = response.body;
else debug(`Failed to fetch icon ${response.status}`);
} else {
debug(`Cannot fetch icon for ${applink.upstreamUri}`);
}
if (dom.window.document.title) applink.label = dom.window.document.title;
}
2022-07-06 19:15:59 +02:00
const data = {
id: uuid.v4(),
accessRestrictionJson: applink.accessRestriction ? JSON.stringify(applink.accessRestriction) : null,
label: applink.label || '',
tagsJson: applink.tags ? JSON.stringify(applink.tags) : null,
icon: applink.icon || null,
upstreamUri: applink.upstreamUri
};
const query = 'INSERT INTO applinks (id, accessRestrictionJson, label, tagsJson, icon, upstreamUri) VALUES (?, ?, ?, ?, ?, ?)';
const args = [ data.id, data.accessRestrictionJson, data.label, data.tagsJson, data.icon, data.upstreamUri ];
const [error] = await safe(database.query(query, args));
if (error) throw error;
return data.id;
}
async function get(applinkId) {
assert.strictEqual(typeof applinkId, 'string');
debug(`get: ${applinkId}`);
const result = await database.query(`SELECT ${APPLINKS_FIELDS} FROM applinks WHERE id = ?`, [ applinkId ]);
if (result.length === 0) throw new BoxError(BoxError.NOT_FOUND, 'Applink not found');
postProcess(result[0]);
return result[0];
}
async function update(applinkId, applink) {
assert.strictEqual(typeof applinkId, 'string');
assert.strictEqual(typeof applink, 'object');
assert.strictEqual(typeof applink.upstreamUri, 'string');
debug(`update: ${applinkId} ${applink.upstreamUri}`, applink);
}
async function remove(applinkId) {
assert.strictEqual(typeof applinkId, 'string');
debug(`remove: ${applinkId}`);
const result = await database.query(`DELETE FROM applinks WHERE id = ?`, [ applinkId ]);
if (result.affectedRows !== 1) throw new BoxError(BoxError.NOT_FOUND, 'Applink not found');
}
2022-07-07 14:11:14 +02:00
async function getIcon(applinkId) {
assert.strictEqual(typeof applinkId, 'string');
debug(`getIcon: ${applinkId}`);
const applink = await get(applinkId);
return applink.icon;
}