@mdguggenbichler/slugbase-core 0.0.16 → 0.0.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/backend/dist/app-factory.d.ts +1 -1
- package/backend/dist/app-factory.d.ts.map +1 -1
- package/backend/dist/app-factory.js +2 -13
- package/backend/dist/app-factory.js.map +1 -1
- package/backend/dist/index.js +1 -1
- package/backend/dist/index.js.map +1 -1
- package/backend/dist/routes/admin/settings.d.ts.map +1 -1
- package/backend/dist/routes/admin/settings.js +0 -281
- package/backend/dist/routes/admin/settings.js.map +1 -1
- package/backend/dist/routes/admin/stats.d.ts.map +1 -1
- package/backend/dist/routes/admin/stats.js +0 -39
- package/backend/dist/routes/admin/stats.js.map +1 -1
- package/backend/dist/routes/admin/teams.d.ts.map +1 -1
- package/backend/dist/routes/admin/teams.js +0 -344
- package/backend/dist/routes/admin/teams.js.map +1 -1
- package/backend/dist/routes/admin/users.d.ts.map +1 -1
- package/backend/dist/routes/admin/users.js +0 -317
- package/backend/dist/routes/admin/users.js.map +1 -1
- package/backend/dist/routes/auth.d.ts.map +1 -1
- package/backend/dist/routes/auth.js +0 -284
- package/backend/dist/routes/auth.js.map +1 -1
- package/backend/dist/routes/bookmarks.d.ts.map +1 -1
- package/backend/dist/routes/bookmarks.js +4 -525
- package/backend/dist/routes/bookmarks.js.map +1 -1
- package/backend/dist/routes/config.d.ts.map +1 -1
- package/backend/dist/routes/config.js +4 -29
- package/backend/dist/routes/config.js.map +1 -1
- package/backend/dist/routes/csrf.d.ts.map +1 -1
- package/backend/dist/routes/csrf.js +0 -24
- package/backend/dist/routes/csrf.js.map +1 -1
- package/backend/dist/routes/dashboard.d.ts.map +1 -1
- package/backend/dist/routes/dashboard.js +0 -35
- package/backend/dist/routes/dashboard.js.map +1 -1
- package/backend/dist/routes/email-verification.d.ts.map +1 -1
- package/backend/dist/routes/email-verification.js +0 -53
- package/backend/dist/routes/email-verification.js.map +1 -1
- package/backend/dist/routes/folders.d.ts.map +1 -1
- package/backend/dist/routes/folders.js +0 -217
- package/backend/dist/routes/folders.js.map +1 -1
- package/backend/dist/routes/go.d.ts.map +1 -1
- package/backend/dist/routes/go.js +0 -95
- package/backend/dist/routes/go.js.map +1 -1
- package/backend/dist/routes/health.d.ts.map +1 -1
- package/backend/dist/routes/health.js +0 -45
- package/backend/dist/routes/health.js.map +1 -1
- package/backend/dist/routes/oidc-providers.d.ts.map +1 -1
- package/backend/dist/routes/oidc-providers.js +0 -221
- package/backend/dist/routes/oidc-providers.js.map +1 -1
- package/backend/dist/routes/password-reset.d.ts.map +1 -1
- package/backend/dist/routes/password-reset.js +0 -67
- package/backend/dist/routes/password-reset.js.map +1 -1
- package/backend/dist/routes/tags.d.ts.map +1 -1
- package/backend/dist/routes/tags.js +0 -174
- package/backend/dist/routes/tags.js.map +1 -1
- package/backend/dist/routes/teams.d.ts.map +1 -1
- package/backend/dist/routes/teams.js +0 -36
- package/backend/dist/routes/teams.js.map +1 -1
- package/backend/dist/routes/tokens.d.ts.map +1 -1
- package/backend/dist/routes/tokens.js +0 -108
- package/backend/dist/routes/tokens.js.map +1 -1
- package/backend/dist/routes/users.d.ts.map +1 -1
- package/backend/dist/routes/users.js +0 -81
- package/backend/dist/routes/users.js.map +1 -1
- package/backend/dist/utils/ai-feature.d.ts +9 -7
- package/backend/dist/utils/ai-feature.d.ts.map +1 -1
- package/backend/dist/utils/ai-feature.js +29 -13
- package/backend/dist/utils/ai-feature.js.map +1 -1
- package/frontend/src/App.tsx +4 -2
- package/frontend/src/components/admin/AdminAI.tsx +68 -58
- package/frontend/src/contexts/AppConfigContext.tsx +7 -0
- package/package.json +1 -1
|
@@ -25,103 +25,6 @@ async function recordAiSuggestionUsage(userId, used) {
|
|
|
25
25
|
// Table may not exist yet; do not fail the bookmark request
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
|
-
/**
|
|
29
|
-
* @swagger
|
|
30
|
-
* /api/bookmarks:
|
|
31
|
-
* get:
|
|
32
|
-
* summary: Get all bookmarks
|
|
33
|
-
* description: Returns all bookmarks for the authenticated user, including own bookmarks and bookmarks shared via teams or users. Supports filtering by folder and tag.
|
|
34
|
-
* tags: [Bookmarks]
|
|
35
|
-
* security:
|
|
36
|
-
* - cookieAuth: []
|
|
37
|
-
* - bearerAuth: []
|
|
38
|
-
* parameters:
|
|
39
|
-
* - in: query
|
|
40
|
-
* name: folder_id
|
|
41
|
-
* schema:
|
|
42
|
-
* type: string
|
|
43
|
-
* description: Filter bookmarks by folder ID
|
|
44
|
-
* example: "123e4567-e89b-12d3-a456-426614174000"
|
|
45
|
-
* - in: query
|
|
46
|
-
* name: tag_id
|
|
47
|
-
* schema:
|
|
48
|
-
* type: string
|
|
49
|
-
* description: Filter bookmarks by tag ID
|
|
50
|
-
* example: "123e4567-e89b-12d3-a456-426614174000"
|
|
51
|
-
* - in: query
|
|
52
|
-
* name: limit
|
|
53
|
-
* schema:
|
|
54
|
-
* type: integer
|
|
55
|
-
* default: 50
|
|
56
|
-
* description: Max items per page (1-100)
|
|
57
|
-
* - in: query
|
|
58
|
-
* name: offset
|
|
59
|
-
* schema:
|
|
60
|
-
* type: integer
|
|
61
|
-
* default: 0
|
|
62
|
-
* description: Number of items to skip
|
|
63
|
-
* responses:
|
|
64
|
-
* 200:
|
|
65
|
-
* description: List of bookmarks
|
|
66
|
-
* content:
|
|
67
|
-
* application/json:
|
|
68
|
-
* schema:
|
|
69
|
-
* type: array
|
|
70
|
-
* items:
|
|
71
|
-
* type: object
|
|
72
|
-
* properties:
|
|
73
|
-
* id:
|
|
74
|
-
* type: string
|
|
75
|
-
* example: "123e4567-e89b-12d3-a456-426614174000"
|
|
76
|
-
* title:
|
|
77
|
-
* type: string
|
|
78
|
-
* example: "Example Bookmark"
|
|
79
|
-
* url:
|
|
80
|
-
* type: string
|
|
81
|
-
* example: "https://example.com"
|
|
82
|
-
* slug:
|
|
83
|
-
* type: string
|
|
84
|
-
* nullable: true
|
|
85
|
-
* example: "example-slug"
|
|
86
|
-
* forwarding_enabled:
|
|
87
|
-
* type: boolean
|
|
88
|
-
* example: true
|
|
89
|
-
* bookmark_type:
|
|
90
|
-
* type: string
|
|
91
|
-
* enum: [own, shared]
|
|
92
|
-
* example: "own"
|
|
93
|
-
* folders:
|
|
94
|
-
* type: array
|
|
95
|
-
* items:
|
|
96
|
-
* type: object
|
|
97
|
-
* properties:
|
|
98
|
-
* id:
|
|
99
|
-
* type: string
|
|
100
|
-
* name:
|
|
101
|
-
* type: string
|
|
102
|
-
* icon:
|
|
103
|
-
* type: string
|
|
104
|
-
* nullable: true
|
|
105
|
-
* tags:
|
|
106
|
-
* type: array
|
|
107
|
-
* items:
|
|
108
|
-
* type: object
|
|
109
|
-
* properties:
|
|
110
|
-
* id:
|
|
111
|
-
* type: string
|
|
112
|
-
* name:
|
|
113
|
-
* type: string
|
|
114
|
-
* shared_teams:
|
|
115
|
-
* type: array
|
|
116
|
-
* items:
|
|
117
|
-
* type: object
|
|
118
|
-
* shared_users:
|
|
119
|
-
* type: array
|
|
120
|
-
* items:
|
|
121
|
-
* type: object
|
|
122
|
-
* 401:
|
|
123
|
-
* description: Unauthorized
|
|
124
|
-
*/
|
|
125
28
|
// Get all bookmarks for user (including shared bookmarks)
|
|
126
29
|
router.get('/', async (req, res) => {
|
|
127
30
|
const authReq = req;
|
|
@@ -445,79 +348,6 @@ router.get('/', async (req, res) => {
|
|
|
445
348
|
res.status(500).json({ error: error.message });
|
|
446
349
|
}
|
|
447
350
|
});
|
|
448
|
-
/**
|
|
449
|
-
* @swagger
|
|
450
|
-
* /api/bookmarks/{id}:
|
|
451
|
-
* get:
|
|
452
|
-
* summary: Get bookmark by ID
|
|
453
|
-
* description: Returns a single bookmark by ID. User must own the bookmark or have access via sharing.
|
|
454
|
-
* tags: [Bookmarks]
|
|
455
|
-
* security:
|
|
456
|
-
* - cookieAuth: []
|
|
457
|
-
* - bearerAuth: []
|
|
458
|
-
* parameters:
|
|
459
|
-
* - in: path
|
|
460
|
-
* name: id
|
|
461
|
-
* required: true
|
|
462
|
-
* schema:
|
|
463
|
-
* type: string
|
|
464
|
-
* description: Bookmark ID
|
|
465
|
-
* example: "123e4567-e89b-12d3-a456-426614174000"
|
|
466
|
-
* responses:
|
|
467
|
-
* 200:
|
|
468
|
-
* description: Bookmark details
|
|
469
|
-
* content:
|
|
470
|
-
* application/json:
|
|
471
|
-
* schema:
|
|
472
|
-
* type: object
|
|
473
|
-
* properties:
|
|
474
|
-
* id:
|
|
475
|
-
* type: string
|
|
476
|
-
* title:
|
|
477
|
-
* type: string
|
|
478
|
-
* url:
|
|
479
|
-
* type: string
|
|
480
|
-
* slug:
|
|
481
|
-
* type: string
|
|
482
|
-
* nullable: true
|
|
483
|
-
* forwarding_enabled:
|
|
484
|
-
* type: boolean
|
|
485
|
-
* folders:
|
|
486
|
-
* type: array
|
|
487
|
-
* tags:
|
|
488
|
-
* type: array
|
|
489
|
-
* shared_teams:
|
|
490
|
-
* type: array
|
|
491
|
-
* shared_users:
|
|
492
|
-
* type: array
|
|
493
|
-
* 404:
|
|
494
|
-
* description: Bookmark not found
|
|
495
|
-
* 401:
|
|
496
|
-
* description: Unauthorized
|
|
497
|
-
*/
|
|
498
|
-
/**
|
|
499
|
-
* @swagger
|
|
500
|
-
* /api/bookmarks/search:
|
|
501
|
-
* get:
|
|
502
|
-
* summary: Search bookmarks, folders, and tags
|
|
503
|
-
* description: Global search across bookmarks, folders, and tags
|
|
504
|
-
* tags: [Bookmarks]
|
|
505
|
-
* security:
|
|
506
|
-
* - cookieAuth: []
|
|
507
|
-
* - bearerAuth: []
|
|
508
|
-
* parameters:
|
|
509
|
-
* - in: query
|
|
510
|
-
* name: q
|
|
511
|
-
* required: true
|
|
512
|
-
* schema:
|
|
513
|
-
* type: string
|
|
514
|
-
* description: Search query
|
|
515
|
-
* responses:
|
|
516
|
-
* 200:
|
|
517
|
-
* description: Search results
|
|
518
|
-
* 401:
|
|
519
|
-
* description: Unauthorized
|
|
520
|
-
*/
|
|
521
351
|
// Search endpoint (must be before /:id route)
|
|
522
352
|
router.get('/search', async (req, res) => {
|
|
523
353
|
const authReq = req;
|
|
@@ -611,26 +441,6 @@ router.get('/search', async (req, res) => {
|
|
|
611
441
|
res.status(500).json({ error: 'Search failed' });
|
|
612
442
|
}
|
|
613
443
|
});
|
|
614
|
-
/**
|
|
615
|
-
* @swagger
|
|
616
|
-
* /api/bookmarks/export:
|
|
617
|
-
* get:
|
|
618
|
-
* summary: Export bookmarks as JSON
|
|
619
|
-
* description: Export all user's bookmarks as JSON
|
|
620
|
-
* tags: [Bookmarks]
|
|
621
|
-
* security:
|
|
622
|
-
* - cookieAuth: []
|
|
623
|
-
* - bearerAuth: []
|
|
624
|
-
* responses:
|
|
625
|
-
* 200:
|
|
626
|
-
* description: JSON export of bookmarks
|
|
627
|
-
* content:
|
|
628
|
-
* application/json:
|
|
629
|
-
* schema:
|
|
630
|
-
* type: array
|
|
631
|
-
* 401:
|
|
632
|
-
* description: Unauthorized
|
|
633
|
-
*/
|
|
634
444
|
// Export bookmarks as JSON (must be before /:id route)
|
|
635
445
|
router.get('/export', async (req, res) => {
|
|
636
446
|
const authReq = req;
|
|
@@ -793,51 +603,6 @@ router.get('/ids', async (req, res) => {
|
|
|
793
603
|
res.status(500).json({ error: 'Failed to fetch bookmark IDs' });
|
|
794
604
|
}
|
|
795
605
|
});
|
|
796
|
-
/**
|
|
797
|
-
* @swagger
|
|
798
|
-
* /api/bookmarks/ai-suggest:
|
|
799
|
-
* post:
|
|
800
|
-
* summary: Get AI suggestions for bookmark metadata
|
|
801
|
-
* description: Returns suggested title, slug, and tags for a URL. Requires AI feature enabled. Non-blocking; bookmark creation never depends on this.
|
|
802
|
-
* tags: [Bookmarks]
|
|
803
|
-
* security:
|
|
804
|
-
* - cookieAuth: []
|
|
805
|
-
* - bearerAuth: []
|
|
806
|
-
* requestBody:
|
|
807
|
-
* required: true
|
|
808
|
-
* content:
|
|
809
|
-
* application/json:
|
|
810
|
-
* schema:
|
|
811
|
-
* type: object
|
|
812
|
-
* required: [url]
|
|
813
|
-
* properties:
|
|
814
|
-
* url:
|
|
815
|
-
* type: string
|
|
816
|
-
* format: uri
|
|
817
|
-
* page_title:
|
|
818
|
-
* type: string
|
|
819
|
-
* responses:
|
|
820
|
-
* 200:
|
|
821
|
-
* description: AI suggestions
|
|
822
|
-
* content:
|
|
823
|
-
* application/json:
|
|
824
|
-
* schema:
|
|
825
|
-
* type: object
|
|
826
|
-
* properties:
|
|
827
|
-
* title: { type: string }
|
|
828
|
-
* slug: { type: string }
|
|
829
|
-
* tags: { type: array, items: { type: string } }
|
|
830
|
-
* language: { type: string }
|
|
831
|
-
* confidence: { type: number }
|
|
832
|
-
* 400:
|
|
833
|
-
* description: Invalid URL
|
|
834
|
-
* 403:
|
|
835
|
-
* description: AI feature disabled or not available for plan
|
|
836
|
-
* 408:
|
|
837
|
-
* description: AI request timeout
|
|
838
|
-
* 503:
|
|
839
|
-
* description: AI not configured
|
|
840
|
-
*/
|
|
841
606
|
router.post('/ai-suggest', async (req, res) => {
|
|
842
607
|
const authReq = req;
|
|
843
608
|
try {
|
|
@@ -850,11 +615,12 @@ router.post('/ai-suggest', async (req, res) => {
|
|
|
850
615
|
if (!urlValidation.valid) {
|
|
851
616
|
return res.status(400).json({ error: urlValidation.error });
|
|
852
617
|
}
|
|
853
|
-
const
|
|
618
|
+
const tenantId = getTenantId(req);
|
|
619
|
+
const enabled = await isAISuggestionsEnabled(userId, tenantId);
|
|
854
620
|
if (!enabled) {
|
|
855
621
|
return res.status(403).json({ error: 'AI suggestions are not available' });
|
|
856
622
|
}
|
|
857
|
-
const apiKey = await getAIApiKey();
|
|
623
|
+
const apiKey = await getAIApiKey(tenantId);
|
|
858
624
|
if (!apiKey) {
|
|
859
625
|
return res.status(503).json({ error: 'AI is not configured' });
|
|
860
626
|
}
|
|
@@ -889,7 +655,7 @@ router.post('/ai-suggest', async (req, res) => {
|
|
|
889
655
|
const pageTitleToUse = typeof pageTitle === 'string' && pageTitle.trim()
|
|
890
656
|
? pageTitle.trim()
|
|
891
657
|
: fetchedTitle;
|
|
892
|
-
const model = await getAIModel();
|
|
658
|
+
const model = await getAIModel(tenantId);
|
|
893
659
|
const result = await callAIProvider(sanitizedUrl, pageTitleToUse, fetchedDescription, apiKey, model, 10000, userLanguage, siteName);
|
|
894
660
|
if (!result) {
|
|
895
661
|
return res.status(503).json({ error: 'AI suggestion failed' });
|
|
@@ -976,31 +742,6 @@ router.get('/:id', async (req, res) => {
|
|
|
976
742
|
res.status(500).json({ error: error.message });
|
|
977
743
|
}
|
|
978
744
|
});
|
|
979
|
-
/**
|
|
980
|
-
* @swagger
|
|
981
|
-
* /api/bookmarks/{id}/track-access:
|
|
982
|
-
* post:
|
|
983
|
-
* summary: Track bookmark access
|
|
984
|
-
* description: Increments access_count and updates last_accessed_at for a bookmark when it is opened
|
|
985
|
-
* tags: [Bookmarks]
|
|
986
|
-
* security:
|
|
987
|
-
* - cookieAuth: []
|
|
988
|
-
* - bearerAuth: []
|
|
989
|
-
* parameters:
|
|
990
|
-
* - in: path
|
|
991
|
-
* name: id
|
|
992
|
-
* required: true
|
|
993
|
-
* schema:
|
|
994
|
-
* type: string
|
|
995
|
-
* description: Bookmark ID
|
|
996
|
-
* responses:
|
|
997
|
-
* 200:
|
|
998
|
-
* description: Access tracked successfully
|
|
999
|
-
* 404:
|
|
1000
|
-
* description: Bookmark not found
|
|
1001
|
-
* 401:
|
|
1002
|
-
* description: Unauthorized
|
|
1003
|
-
*/
|
|
1004
745
|
// Track bookmark access (must be before PUT /:id)
|
|
1005
746
|
router.post('/:id/track-access', async (req, res) => {
|
|
1006
747
|
const authReq = req;
|
|
@@ -1024,97 +765,6 @@ router.post('/:id/track-access', async (req, res) => {
|
|
|
1024
765
|
res.status(500).json({ error: error.message });
|
|
1025
766
|
}
|
|
1026
767
|
});
|
|
1027
|
-
/**
|
|
1028
|
-
* @swagger
|
|
1029
|
-
* /api/bookmarks:
|
|
1030
|
-
* post:
|
|
1031
|
-
* summary: Create a new bookmark
|
|
1032
|
-
* description: Creates a new bookmark. Slug is required only if forwarding is enabled. Can assign to multiple folders, tags, and share with users/teams.
|
|
1033
|
-
* tags: [Bookmarks]
|
|
1034
|
-
* security:
|
|
1035
|
-
* - cookieAuth: []
|
|
1036
|
-
* - bearerAuth: []
|
|
1037
|
-
* requestBody:
|
|
1038
|
-
* required: true
|
|
1039
|
-
* content:
|
|
1040
|
-
* application/json:
|
|
1041
|
-
* schema:
|
|
1042
|
-
* type: object
|
|
1043
|
-
* required:
|
|
1044
|
-
* - title
|
|
1045
|
-
* - url
|
|
1046
|
-
* properties:
|
|
1047
|
-
* title:
|
|
1048
|
-
* type: string
|
|
1049
|
-
* example: "Example Bookmark"
|
|
1050
|
-
* url:
|
|
1051
|
-
* type: string
|
|
1052
|
-
* format: uri
|
|
1053
|
-
* example: "https://example.com"
|
|
1054
|
-
* slug:
|
|
1055
|
-
* type: string
|
|
1056
|
-
* nullable: true
|
|
1057
|
-
* description: Required if forwarding_enabled is true, optional otherwise
|
|
1058
|
-
* example: "example-slug"
|
|
1059
|
-
* forwarding_enabled:
|
|
1060
|
-
* type: boolean
|
|
1061
|
-
* default: false
|
|
1062
|
-
* example: true
|
|
1063
|
-
* folder_ids:
|
|
1064
|
-
* type: array
|
|
1065
|
-
* items:
|
|
1066
|
-
* type: string
|
|
1067
|
-
* description: Array of folder IDs to assign bookmark to
|
|
1068
|
-
* example: ["123e4567-e89b-12d3-a456-426614174000"]
|
|
1069
|
-
* tag_ids:
|
|
1070
|
-
* type: array
|
|
1071
|
-
* items:
|
|
1072
|
-
* type: string
|
|
1073
|
-
* description: Array of tag IDs to assign to bookmark
|
|
1074
|
-
* example: ["123e4567-e89b-12d3-a456-426614174000"]
|
|
1075
|
-
* team_ids:
|
|
1076
|
-
* type: array
|
|
1077
|
-
* items:
|
|
1078
|
-
* type: string
|
|
1079
|
-
* description: Array of team IDs to share bookmark with
|
|
1080
|
-
* example: ["123e4567-e89b-12d3-a456-426614174000"]
|
|
1081
|
-
* user_ids:
|
|
1082
|
-
* type: array
|
|
1083
|
-
* items:
|
|
1084
|
-
* type: string
|
|
1085
|
-
* description: Array of user IDs to share bookmark with
|
|
1086
|
-
* example: ["123e4567-e89b-12d3-a456-426614174000"]
|
|
1087
|
-
* share_all_teams:
|
|
1088
|
-
* type: boolean
|
|
1089
|
-
* default: false
|
|
1090
|
-
* description: Share bookmark with all teams user is a member of
|
|
1091
|
-
* example: false
|
|
1092
|
-
* responses:
|
|
1093
|
-
* 201:
|
|
1094
|
-
* description: Bookmark created successfully
|
|
1095
|
-
* content:
|
|
1096
|
-
* application/json:
|
|
1097
|
-
* schema:
|
|
1098
|
-
* type: object
|
|
1099
|
-
* properties:
|
|
1100
|
-
* id:
|
|
1101
|
-
* type: string
|
|
1102
|
-
* title:
|
|
1103
|
-
* type: string
|
|
1104
|
-
* url:
|
|
1105
|
-
* type: string
|
|
1106
|
-
* slug:
|
|
1107
|
-
* type: string
|
|
1108
|
-
* nullable: true
|
|
1109
|
-
* forwarding_enabled:
|
|
1110
|
-
* type: boolean
|
|
1111
|
-
* 400:
|
|
1112
|
-
* description: Missing required fields, slug required when forwarding enabled, or slug already exists
|
|
1113
|
-
* 401:
|
|
1114
|
-
* description: Unauthorized
|
|
1115
|
-
* 403:
|
|
1116
|
-
* description: User does not own folder or is not member of team
|
|
1117
|
-
*/
|
|
1118
768
|
// Create bookmark
|
|
1119
769
|
router.post('/', async (req, res) => {
|
|
1120
770
|
const authReq = req;
|
|
@@ -1223,81 +873,6 @@ router.post('/', async (req, res) => {
|
|
|
1223
873
|
res.status(500).json({ error: error.message });
|
|
1224
874
|
}
|
|
1225
875
|
});
|
|
1226
|
-
/**
|
|
1227
|
-
* @swagger
|
|
1228
|
-
* /api/bookmarks/{id}:
|
|
1229
|
-
* put:
|
|
1230
|
-
* summary: Update bookmark
|
|
1231
|
-
* description: Updates an existing bookmark. User must own the bookmark. All fields are optional.
|
|
1232
|
-
* tags: [Bookmarks]
|
|
1233
|
-
* security:
|
|
1234
|
-
* - cookieAuth: []
|
|
1235
|
-
* - bearerAuth: []
|
|
1236
|
-
* parameters:
|
|
1237
|
-
* - in: path
|
|
1238
|
-
* name: id
|
|
1239
|
-
* required: true
|
|
1240
|
-
* schema:
|
|
1241
|
-
* type: string
|
|
1242
|
-
* description: Bookmark ID
|
|
1243
|
-
* example: "123e4567-e89b-12d3-a456-426614174000"
|
|
1244
|
-
* requestBody:
|
|
1245
|
-
* required: true
|
|
1246
|
-
* content:
|
|
1247
|
-
* application/json:
|
|
1248
|
-
* schema:
|
|
1249
|
-
* type: object
|
|
1250
|
-
* properties:
|
|
1251
|
-
* title:
|
|
1252
|
-
* type: string
|
|
1253
|
-
* example: "Updated Bookmark Title"
|
|
1254
|
-
* url:
|
|
1255
|
-
* type: string
|
|
1256
|
-
* format: uri
|
|
1257
|
-
* example: "https://updated-example.com"
|
|
1258
|
-
* slug:
|
|
1259
|
-
* type: string
|
|
1260
|
-
* nullable: true
|
|
1261
|
-
* description: Required if forwarding_enabled is true
|
|
1262
|
-
* example: "updated-slug"
|
|
1263
|
-
* forwarding_enabled:
|
|
1264
|
-
* type: boolean
|
|
1265
|
-
* example: true
|
|
1266
|
-
* folder_ids:
|
|
1267
|
-
* type: array
|
|
1268
|
-
* items:
|
|
1269
|
-
* type: string
|
|
1270
|
-
* description: Array of folder IDs (replaces existing assignments)
|
|
1271
|
-
* tag_ids:
|
|
1272
|
-
* type: array
|
|
1273
|
-
* items:
|
|
1274
|
-
* type: string
|
|
1275
|
-
* description: Array of tag IDs (replaces existing assignments)
|
|
1276
|
-
* team_ids:
|
|
1277
|
-
* type: array
|
|
1278
|
-
* items:
|
|
1279
|
-
* type: string
|
|
1280
|
-
* description: Array of team IDs to share with (replaces existing shares)
|
|
1281
|
-
* user_ids:
|
|
1282
|
-
* type: array
|
|
1283
|
-
* items:
|
|
1284
|
-
* type: string
|
|
1285
|
-
* description: Array of user IDs to share with (replaces existing shares)
|
|
1286
|
-
* share_all_teams:
|
|
1287
|
-
* type: boolean
|
|
1288
|
-
* description: Share with all teams user is a member of
|
|
1289
|
-
* responses:
|
|
1290
|
-
* 200:
|
|
1291
|
-
* description: Bookmark updated successfully
|
|
1292
|
-
* 400:
|
|
1293
|
-
* description: Slug required when forwarding enabled or slug already exists
|
|
1294
|
-
* 401:
|
|
1295
|
-
* description: Unauthorized
|
|
1296
|
-
* 403:
|
|
1297
|
-
* description: User does not own folder or is not member of team
|
|
1298
|
-
* 404:
|
|
1299
|
-
* description: Bookmark not found
|
|
1300
|
-
*/
|
|
1301
876
|
// Update bookmark
|
|
1302
877
|
router.put('/:id', async (req, res) => {
|
|
1303
878
|
const authReq = req;
|
|
@@ -1456,40 +1031,6 @@ router.put('/:id', async (req, res) => {
|
|
|
1456
1031
|
res.status(500).json({ error: error.message });
|
|
1457
1032
|
}
|
|
1458
1033
|
});
|
|
1459
|
-
/**
|
|
1460
|
-
* @swagger
|
|
1461
|
-
* /api/bookmarks/{id}:
|
|
1462
|
-
* delete:
|
|
1463
|
-
* summary: Delete bookmark
|
|
1464
|
-
* description: Deletes a bookmark. User must own the bookmark.
|
|
1465
|
-
* tags: [Bookmarks]
|
|
1466
|
-
* security:
|
|
1467
|
-
* - cookieAuth: []
|
|
1468
|
-
* - bearerAuth: []
|
|
1469
|
-
* parameters:
|
|
1470
|
-
* - in: path
|
|
1471
|
-
* name: id
|
|
1472
|
-
* required: true
|
|
1473
|
-
* schema:
|
|
1474
|
-
* type: string
|
|
1475
|
-
* description: Bookmark ID
|
|
1476
|
-
* example: "123e4567-e89b-12d3-a456-426614174000"
|
|
1477
|
-
* responses:
|
|
1478
|
-
* 200:
|
|
1479
|
-
* description: Bookmark deleted successfully
|
|
1480
|
-
* content:
|
|
1481
|
-
* application/json:
|
|
1482
|
-
* schema:
|
|
1483
|
-
* type: object
|
|
1484
|
-
* properties:
|
|
1485
|
-
* message:
|
|
1486
|
-
* type: string
|
|
1487
|
-
* example: "Bookmark deleted"
|
|
1488
|
-
* 401:
|
|
1489
|
-
* description: Unauthorized
|
|
1490
|
-
* 404:
|
|
1491
|
-
* description: Bookmark not found
|
|
1492
|
-
*/
|
|
1493
1034
|
// Delete bookmark
|
|
1494
1035
|
router.delete('/:id', async (req, res) => {
|
|
1495
1036
|
const authReq = req;
|
|
@@ -1508,68 +1049,6 @@ router.delete('/:id', async (req, res) => {
|
|
|
1508
1049
|
res.status(500).json({ error: error.message });
|
|
1509
1050
|
}
|
|
1510
1051
|
});
|
|
1511
|
-
/**
|
|
1512
|
-
* @swagger
|
|
1513
|
-
* /api/bookmarks/search:
|
|
1514
|
-
* get:
|
|
1515
|
-
* summary: Search bookmarks, folders, and tags
|
|
1516
|
-
* description: Search across bookmarks, folders, and tags for the authenticated user
|
|
1517
|
-
* tags: [Bookmarks]
|
|
1518
|
-
* security:
|
|
1519
|
-
* - cookieAuth: []
|
|
1520
|
-
* - bearerAuth: []
|
|
1521
|
-
* parameters:
|
|
1522
|
-
* - in: query
|
|
1523
|
-
* name: q
|
|
1524
|
-
* required: true
|
|
1525
|
-
* schema:
|
|
1526
|
-
* type: string
|
|
1527
|
-
* description: Search query
|
|
1528
|
-
* example: "example"
|
|
1529
|
-
* responses:
|
|
1530
|
-
* 200:
|
|
1531
|
-
* description: Search results
|
|
1532
|
-
* 401:
|
|
1533
|
-
* description: Unauthorized
|
|
1534
|
-
*/
|
|
1535
|
-
/**
|
|
1536
|
-
* @swagger
|
|
1537
|
-
* /api/bookmarks/import:
|
|
1538
|
-
* post:
|
|
1539
|
-
* summary: Import bookmarks from JSON
|
|
1540
|
-
* description: Import bookmarks from a JSON array
|
|
1541
|
-
* tags: [Bookmarks]
|
|
1542
|
-
* security:
|
|
1543
|
-
* - cookieAuth: []
|
|
1544
|
-
* - bearerAuth: []
|
|
1545
|
-
* requestBody:
|
|
1546
|
-
* required: true
|
|
1547
|
-
* content:
|
|
1548
|
-
* application/json:
|
|
1549
|
-
* schema:
|
|
1550
|
-
* type: object
|
|
1551
|
-
* properties:
|
|
1552
|
-
* bookmarks:
|
|
1553
|
-
* type: array
|
|
1554
|
-
* items:
|
|
1555
|
-
* type: object
|
|
1556
|
-
* properties:
|
|
1557
|
-
* title:
|
|
1558
|
-
* type: string
|
|
1559
|
-
* url:
|
|
1560
|
-
* type: string
|
|
1561
|
-
* slug:
|
|
1562
|
-
* type: string
|
|
1563
|
-
* forwarding_enabled:
|
|
1564
|
-
* type: boolean
|
|
1565
|
-
* responses:
|
|
1566
|
-
* 200:
|
|
1567
|
-
* description: Import successful
|
|
1568
|
-
* 400:
|
|
1569
|
-
* description: Invalid import data
|
|
1570
|
-
* 401:
|
|
1571
|
-
* description: Unauthorized
|
|
1572
|
-
*/
|
|
1573
1052
|
// Import bookmarks from JSON
|
|
1574
1053
|
router.post('/import', async (req, res) => {
|
|
1575
1054
|
const authReq = req;
|