From 928a9184bd377e784dc286f2a87d16529276d712 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ian=20P=C3=B6sse-Koch?= <ian-coding@poesseko.ch>
Date: Tue, 3 Dec 2024 22:24:59 +0100
Subject: [PATCH] add expiring share links to url recipe actions

---
 .../composables/use-group-recipe-actions.ts   | 38 +++++++++++++++++--
 1 file changed, 35 insertions(+), 3 deletions(-)

diff --git a/frontend/composables/use-group-recipe-actions.ts b/frontend/composables/use-group-recipe-actions.ts
index 2701c0fe4c0..915f925472d 100644
--- a/frontend/composables/use-group-recipe-actions.ts
+++ b/frontend/composables/use-group-recipe-actions.ts
@@ -34,7 +34,6 @@ export const useGroupRecipeActions = function (
   orderDirection: string | null = "asc",
 ) {
   const api = useUserApi();
-
   async function refreshGroupRecipeActions() {
     loading.value = true;
     const { data } = await api.groupRecipeActions.getAll(1, -1, { orderBy, orderDirection });
@@ -46,8 +45,40 @@ export const useGroupRecipeActions = function (
     return groupRecipeActions.value;
   });
 
-  function parseRecipeActionUrl(url: string, recipe: Recipe): string {
+  function getTokenLink(token: string, groupSlug: string) {
+    return `${window.location.origin}/g/${groupSlug}/shared/r/${token}`;
+  }
+
+  async function parseRecipeActionUrl(url: string, recipe: Recipe): Promise<string> {
     /* eslint-disable no-template-curly-in-string */
+    const shareLinkRegex = /\$\{share-link-expires-seconds-[0-9]+\}/g;
+    const group = (await api.groups.getOne(recipe.groupId || "")).data;
+
+
+    const shareLinkStringMatches = url.matchAll(shareLinkRegex);
+    if (shareLinkStringMatches) {
+      const shareLinkSet = new Set<string>();
+      for (const match of shareLinkStringMatches) {
+        shareLinkSet.add(match[0]);
+      }
+      const shareLinkStrings = Array.from(shareLinkSet.values());
+
+      for (let i = 0; i < shareLinkStrings.length; i++) {
+        const shareLinkString = shareLinkStrings[i];
+        const seconds = parseInt(shareLinkString.split("-")[4]);
+        const expires = new Date();
+        expires.setSeconds(expires.getSeconds() + seconds);
+
+        const shareLink = await api.recipes.share.createOne({
+          recipeId: recipe.id || "",
+          expiresAt: expires.toISOString(),
+        });
+
+        const groupSlug = group?.slug || "";
+        url = url.replace(shareLinkString, getTokenLink(shareLink.data?.id || "", groupSlug));
+      }
+    }
+
     return url
       .replace("${url}", window.location.href)
       .replace("${id}", recipe.id || "")
@@ -56,10 +87,11 @@ export const useGroupRecipeActions = function (
   };
 
   async function execute(action: GroupRecipeActionOut, recipe: Recipe): Promise<void | RequestResponse<unknown>> {
-    const url = parseRecipeActionUrl(action.url, recipe);
+    const url = await parseRecipeActionUrl(action.url, recipe);
 
     switch (action.actionType) {
       case "link":
+
         window.open(url, "_blank")?.focus();
         return;
       case "post":