stackchain-dashboard/frontend/shared-image-capture.js
timmy fdd3cf03b4
All checks were successful
CI / lint (pull_request) Successful in 1m56s
CI / build-release (pull_request) Successful in 7s
CI / browser-journey (pull_request) Successful in 59s
CI / release-candidate (pull_request) Has been skipped
security: keep mobile share content private (Closes #903)
2026-08-15 16:02:35 +00:00

62 lines
2.7 KiB
JavaScript

(function(root, factory) {
const api = factory();
if (typeof module === 'object' && module.exports) module.exports = api;
else root.sharedImageCapture = api;
})(typeof self !== 'undefined' ? self : this, function() {
'use strict';
const RECORD_ID = 'shared-image';
const TYPES = new Set(['image/png', 'image/jpeg', 'image/webp']);
async function consume({marker, store, restore, restoreContent = () => {}, status = () => {}}) {
if (!marker) return false;
const value = await store?.get(RECORD_ID);
const attachments = Array.isArray(value?.attachments) ? value.attachments : null;
if (marker === 'bundle') {
const content = {
title:typeof value?.title === 'string' ? value.title.slice(0, 255) : '',
text:typeof value?.text === 'string' ? value.text.slice(0, 10000) : '',
url:typeof value?.url === 'string' ? value.url.slice(0, 2048) : '',
};
const invalidAttachments = !attachments || attachments.length > 5 || attachments.some(attachment =>
!attachment?.blob || !attachment.filename || !TYPES.has(String(attachment.contentType || '')));
if (invalidAttachments || (!attachments.length && !Object.values(content).some(Boolean))) {
status('The shared content is unavailable. Share it again.');
return false;
}
restoreContent(content);
if (attachments.length) restore(attachments);
await store.delete(RECORD_ID);
const noun = attachments.length === 1 ? 'screenshot' : attachments.length > 1 ? 'screenshots' : 'content';
status(attachments.length
? 'Shared content and ' + (attachments.length > 1 ? attachments.length + ' ' : '') + noun + ' ready to file with this issue.'
: 'Shared content ready to file with this issue.');
return true;
}
if (!['image', 'images'].includes(marker)) {
status('Share one PNG, JPEG, or WebP screenshot.');
return false;
}
if (marker === 'images') {
if (!attachments?.length || attachments.length > 5 || attachments.some(attachment =>
!attachment?.blob || !attachment.filename || !TYPES.has(String(attachment.contentType || '')))) {
status('The shared screenshots are unavailable. Share them again.');
return false;
}
restore(attachments);
await store.delete(RECORD_ID);
status(attachments.length + ' shared screenshots ready to file with this issue.');
return true;
}
if (!value?.blob || !value.filename || !TYPES.has(String(value.contentType || ''))) {
status('The shared screenshot is unavailable. Share it again.');
return false;
}
restore(value);
await store.delete(RECORD_ID);
status('Shared screenshot ready to file with this issue.');
return true;
}
return {consume, RECORD_ID};
});