Subject: [PATCH links] Add audit log when bookmarks are imported via the import tool.

From: Peter Sanchez <[email-masked]>
Date: Tue, 25 Feb 2025 07:25:00 -0600

---
 core/import.go      | 52 ++++++++++++++++++++++++++++++++++++++-------
 models/audit_log.go |  7 +++---
 2 files changed, 48 insertions(+), 11 deletions(-)

diff --git a/core/import.go b/core/import.go
index 59e2437..1671f47 100644
--- a/core/import.go
+++ b/core/import.go
@@ -4,6 +4,7 @@ import (
 	"context"
 	"database/sql"
 	"encoding/json"
+	"fmt"
 	"links"
 	"links/models"
 	"mime/multipart"
@@ -374,7 +375,7 @@ func ImportFromPinBoard(c echo.Context, src multipart.File,
 		return err
 	}
 
-	var start, end int
+	var listlen, start, end int
 	step := 100
 
 	adapter := &importAdapter{
@@ -387,9 +388,10 @@ func ImportFromPinBoard(c echo.Context, src multipart.File,
 	gctx := c.(*server.Context)
 	billEnabled := links.BillingEnabled(gctx.Server.Config)
 
-	for start < len(pinBoardList) {
-		if end+step > len(pinBoardList) {
-			end = len(pinBoardList)
+	listlen = len(pinBoardList)
+	for start < listlen {
+		if end+step > listlen {
+			end = listlen
 		} else {
 			end += step
 		}
@@ -414,6 +416,23 @@ func ImportFromPinBoard(c echo.Context, src multipart.File,
 
 		start += step
 	}
+
+	if listlen > 0 {
+		mdata := make(map[string]any)
+		mdata["org_id"] = org.ID
+		err := models.RecordAuditLog(
+			c.Request().Context(),
+			int(user.ID),
+			c.RealIP(),
+			models.LOG_BOOKMARK_IMPORTED,
+			fmt.Sprintf("Imported %d Pinboard bookmarks into organization %s.", listlen, org.Slug),
+			mdata,
+		)
+		if err != nil {
+			return err
+		}
+	}
+
 	return nil
 }
 
@@ -493,7 +512,7 @@ func ImportFromHTML(c echo.Context, src multipart.File,
 		htmlList = append(htmlList, l)
 	}
 
-	var start, end int
+	var listlen, start, end int
 	step := 100
 
 	adapter := &importAdapter{
@@ -506,9 +525,10 @@ func ImportFromHTML(c echo.Context, src multipart.File,
 	gctx := c.(*server.Context)
 	billEnabled := links.BillingEnabled(gctx.Server.Config)
 
-	for start < len(htmlList) {
-		if end+step > len(htmlList) {
-			end = len(htmlList)
+	listlen = len(htmlList)
+	for start < listlen {
+		if end+step > listlen {
+			end = listlen
 		} else {
 			end += step
 		}
@@ -533,5 +553,21 @@ func ImportFromHTML(c echo.Context, src multipart.File,
 
 		start += step
 	}
+
+	if listlen > 0 {
+		mdata := make(map[string]any)
+		mdata["org_id"] = org.ID
+		err := models.RecordAuditLog(
+			c.Request().Context(),
+			int(user.ID),
+			c.RealIP(),
+			models.LOG_BOOKMARK_IMPORTED,
+			fmt.Sprintf("Imported %d bookmarks into organization %s.", listlen, org.Slug),
+			mdata,
+		)
+		if err != nil {
+			return err
+		}
+	}
 	return nil
 }
diff --git a/models/audit_log.go b/models/audit_log.go
index 5e5f268..4a9301b 100644
--- a/models/audit_log.go
+++ b/models/audit_log.go
@@ -19,9 +19,10 @@ const (
 	LOG_ORG_ADDED   = "organization_added"
 	LOG_ORG_UPDATED = "organization_updated"
 
-	LOG_BOOKMARK_ADDED   = "bookmark_added"
-	LOG_BOOKMARK_UPDATED = "bookmark_added"
-	LOG_BOOKMARK_DELETED = "bookmark_added"
+	LOG_BOOKMARK_ADDED    = "bookmark_added"
+	LOG_BOOKMARK_UPDATED  = "bookmark_added"
+	LOG_BOOKMARK_DELETED  = "bookmark_added"
+	LOG_BOOKMARK_IMPORTED = "bookmarks_imported"
 
 	LOG_NOTE_ADDED   = "note_added"
 	LOG_NOTE_UPDATED = "note_added"
-- 
2.47.2

---

From: "Peter Sanchez" <[email-masked]>
Date: Tue, 25 Feb 2025 07:31:44 -0600

Applied.

To [email-masked]:~netlandish/links
   5c1230c..864c750  master -> master