summaryrefslogtreecommitdiff
path: root/viewer-bff/public/app.js
blob: ecbe3fbd9ac0f18c9272c6cea43b3da4362733cb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
const tokenInput = document.getElementById("tokenInput");
const objectKeysInput = document.getElementById("objectKeysInput");
const permissionsOutput = document.getElementById("permissionsOutput");
const gallery = document.getElementById("gallery");

const loadPermissionsBtn = document.getElementById("loadPermissionsBtn");
const buildGalleryBtn = document.getElementById("buildGalleryBtn");

let currentPermissions = null;

function getToken() {
  return tokenInput.value.trim();
}

function parseObjectKeys() {
  return objectKeysInput.value
    .split("\n")
    .map((line) => line.trim())
    .filter(Boolean);
}

function isAllowedByPermissions(objectKey, permissions) {
  if (!permissions) return false;
  if (permissions.allowAll) return true;
  const prefixes = permissions.allowedPrefixes || [];
  return prefixes.some((prefix) => objectKey.startsWith(prefix));
}

async function callJson(url, options = {}) {
  const token = getToken();
  const headers = {
    "Content-Type": "application/json",
    ...(options.headers || {})
  };
  if (token) {
    headers.Authorization = `Bearer ${token}`;
  }

  const response = await fetch(url, { ...options, headers });
  const payload = await response.json().catch(() => ({}));
  if (!response.ok) {
    throw new Error(payload.message || `HTTP ${response.status}`);
  }
  return payload;
}

loadPermissionsBtn.addEventListener("click", async () => {
  try {
    const perms = await callJson("/api/me/permissions");
    currentPermissions = perms;
    permissionsOutput.textContent = JSON.stringify(perms, null, 2);
  } catch (error) {
    permissionsOutput.textContent = `Erreur: ${error.message}`;
  }
});

buildGalleryBtn.addEventListener("click", async () => {
  gallery.innerHTML = "";
  const keys = parseObjectKeys();

  if (!currentPermissions) {
    permissionsOutput.textContent = "Charger d'abord les permissions.";
    return;
  }

  if (!keys.length) {
    permissionsOutput.textContent = "Ajouter au moins une objectKey.";
    return;
  }

  for (const objectKey of keys) {
    const card = document.createElement("article");
    card.className = "card";

    const img = document.createElement("img");
    img.className = "thumb";
    img.alt = objectKey;

    const keyP = document.createElement("p");
    keyP.className = "key";
    keyP.textContent = objectKey;

    const openBtn = document.createElement("button");
    openBtn.textContent = "Ouvrir";
    openBtn.disabled = !isAllowedByPermissions(objectKey, currentPermissions);

    openBtn.addEventListener("click", async () => {
      try {
        const presign = await callJson("/api/media/presign", {
          method: "POST",
          body: JSON.stringify({ objectKey })
        });
        const signedUrl = presign.url;
        img.src = signedUrl;
        window.open(signedUrl, "_blank", "noopener,noreferrer");
      } catch (error) {
        alert(`Presign refuse: ${error.message}`);
      }
    });

    if (!openBtn.disabled) {
      // Previsualisation opportuniste pour les objets autorises.
      callJson("/api/media/presign", {
        method: "POST",
        body: JSON.stringify({ objectKey })
      })
        .then((presign) => {
          img.src = presign.url;
        })
        .catch(() => {
          img.alt = "Previsualisation indisponible";
        });
    } else {
      img.alt = "Acces refuse (roles)";
    }

    card.appendChild(img);
    card.appendChild(keyP);
    card.appendChild(openBtn);
    gallery.appendChild(card);
  }
});