@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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"teams.d.ts","sourceRoot":"","sources":["../../src/routes/teams.ts"],"names":[],"mappings":"AAKA,QAAA,MAAM,MAAM,4CAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"teams.d.ts","sourceRoot":"","sources":["../../src/routes/teams.ts"],"names":[],"mappings":"AAKA,QAAA,MAAM,MAAM,4CAAW,CAAC;AAsBxB,eAAe,MAAM,CAAC"}
|
|
@@ -4,42 +4,6 @@ import { requireAuth } from '../middleware/auth.js';
|
|
|
4
4
|
import { getTenantId } from '../utils/tenant.js';
|
|
5
5
|
const router = Router();
|
|
6
6
|
router.use(requireAuth());
|
|
7
|
-
/**
|
|
8
|
-
* @swagger
|
|
9
|
-
* /api/teams:
|
|
10
|
-
* get:
|
|
11
|
-
* summary: Get teams for current user
|
|
12
|
-
* description: Returns all teams that the authenticated user is a member of
|
|
13
|
-
* tags: [Teams]
|
|
14
|
-
* security:
|
|
15
|
-
* - cookieAuth: []
|
|
16
|
-
* - bearerAuth: []
|
|
17
|
-
* responses:
|
|
18
|
-
* 200:
|
|
19
|
-
* description: List of teams the user is a member of
|
|
20
|
-
* content:
|
|
21
|
-
* application/json:
|
|
22
|
-
* schema:
|
|
23
|
-
* type: array
|
|
24
|
-
* items:
|
|
25
|
-
* type: object
|
|
26
|
-
* properties:
|
|
27
|
-
* id:
|
|
28
|
-
* type: string
|
|
29
|
-
* example: "123e4567-e89b-12d3-a456-426614174000"
|
|
30
|
-
* name:
|
|
31
|
-
* type: string
|
|
32
|
-
* example: "Development Team"
|
|
33
|
-
* description:
|
|
34
|
-
* type: string
|
|
35
|
-
* nullable: true
|
|
36
|
-
* example: "Team for development work"
|
|
37
|
-
* created_at:
|
|
38
|
-
* type: string
|
|
39
|
-
* format: date-time
|
|
40
|
-
* 401:
|
|
41
|
-
* description: Unauthorized
|
|
42
|
-
*/
|
|
43
7
|
router.get('/', async (req, res) => {
|
|
44
8
|
const authReq = req;
|
|
45
9
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"teams.js","sourceRoot":"","sources":["../../src/routes/teams.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AACvC,OAAO,EAAe,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACjE,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC;AACxB,MAAM,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC;AAE1B
|
|
1
|
+
{"version":3,"file":"teams.js","sourceRoot":"","sources":["../../src/routes/teams.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AACvC,OAAO,EAAe,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACjE,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC;AACxB,MAAM,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC;AAE1B,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;IACjC,MAAM,OAAO,GAAG,GAAkB,CAAC;IACnC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,OAAO,CAAC,IAAK,CAAC,EAAE,CAAC;QAChC,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;QAClC,MAAM,KAAK,GAAG,MAAM,KAAK,CACvB;;;uBAGiB,EACjB,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAC7B,CAAC;QACF,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACxE,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACtB,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACpB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IACjD,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,eAAe,MAAM,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../../src/routes/tokens.ts"],"names":[],"mappings":"AAMA,QAAA,MAAM,MAAM,4CAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../../src/routes/tokens.ts"],"names":[],"mappings":"AAMA,QAAA,MAAM,MAAM,4CAAW,CAAC;AA6CxB,eAAe,MAAM,CAAC"}
|
|
@@ -5,41 +5,6 @@ import * as apiTokens from '../services/api-tokens.js';
|
|
|
5
5
|
import { getTenantId } from '../utils/tenant.js';
|
|
6
6
|
const router = Router();
|
|
7
7
|
router.use(requireAuth());
|
|
8
|
-
/**
|
|
9
|
-
* @swagger
|
|
10
|
-
* /api/tokens:
|
|
11
|
-
* get:
|
|
12
|
-
* summary: List API tokens
|
|
13
|
-
* description: Returns the authenticated user's API tokens. Tokens are masked (sb_********************************). Never returns plaintext.
|
|
14
|
-
* tags: [API Tokens]
|
|
15
|
-
* security:
|
|
16
|
-
* - cookieAuth: []
|
|
17
|
-
* - bearerAuth: []
|
|
18
|
-
* - apiTokenAuth: []
|
|
19
|
-
* responses:
|
|
20
|
-
* 200:
|
|
21
|
-
* description: List of tokens
|
|
22
|
-
* content:
|
|
23
|
-
* application/json:
|
|
24
|
-
* schema:
|
|
25
|
-
* type: array
|
|
26
|
-
* items:
|
|
27
|
-
* type: object
|
|
28
|
-
* properties:
|
|
29
|
-
* id:
|
|
30
|
-
* type: string
|
|
31
|
-
* name:
|
|
32
|
-
* type: string
|
|
33
|
-
* created_at:
|
|
34
|
-
* type: string
|
|
35
|
-
* format: date-time
|
|
36
|
-
* last_used_at:
|
|
37
|
-
* type: string
|
|
38
|
-
* format: date-time
|
|
39
|
-
* nullable: true
|
|
40
|
-
* 401:
|
|
41
|
-
* description: Unauthorized
|
|
42
|
-
*/
|
|
43
8
|
router.get('/', async (req, res) => {
|
|
44
9
|
const authReq = req;
|
|
45
10
|
const userId = authReq.user.id;
|
|
@@ -52,54 +17,6 @@ router.get('/', async (req, res) => {
|
|
|
52
17
|
res.status(500).json({ error: error.message });
|
|
53
18
|
}
|
|
54
19
|
});
|
|
55
|
-
/**
|
|
56
|
-
* @swagger
|
|
57
|
-
* /api/tokens:
|
|
58
|
-
* post:
|
|
59
|
-
* summary: Create API token
|
|
60
|
-
* description: Creates a new personal API token. The plaintext token is returned ONLY ONCE. Store it securely; it cannot be retrieved again.
|
|
61
|
-
* tags: [API Tokens]
|
|
62
|
-
* security:
|
|
63
|
-
* - cookieAuth: []
|
|
64
|
-
* - bearerAuth: []
|
|
65
|
-
* requestBody:
|
|
66
|
-
* required: true
|
|
67
|
-
* content:
|
|
68
|
-
* application/json:
|
|
69
|
-
* schema:
|
|
70
|
-
* type: object
|
|
71
|
-
* required:
|
|
72
|
-
* - name
|
|
73
|
-
* properties:
|
|
74
|
-
* name:
|
|
75
|
-
* type: string
|
|
76
|
-
* description: Descriptive name for the token (e.g. CLI, CI/CD)
|
|
77
|
-
* maxLength: 100
|
|
78
|
-
* responses:
|
|
79
|
-
* 200:
|
|
80
|
-
* description: Token created (plaintext returned once)
|
|
81
|
-
* content:
|
|
82
|
-
* application/json:
|
|
83
|
-
* schema:
|
|
84
|
-
* type: object
|
|
85
|
-
* properties:
|
|
86
|
-
* token:
|
|
87
|
-
* type: string
|
|
88
|
-
* description: The plaintext token. Store securely; never shown again.
|
|
89
|
-
* id:
|
|
90
|
-
* type: string
|
|
91
|
-
* name:
|
|
92
|
-
* type: string
|
|
93
|
-
* created_at:
|
|
94
|
-
* type: string
|
|
95
|
-
* format: date-time
|
|
96
|
-
* 400:
|
|
97
|
-
* description: Validation error (name required, max tokens exceeded)
|
|
98
|
-
* 401:
|
|
99
|
-
* description: Unauthorized
|
|
100
|
-
* 429:
|
|
101
|
-
* description: Too many token creation attempts
|
|
102
|
-
*/
|
|
103
20
|
router.post('/', tokenCreateRateLimiter, async (req, res) => {
|
|
104
21
|
const authReq = req;
|
|
105
22
|
const userId = authReq.user.id;
|
|
@@ -114,31 +31,6 @@ router.post('/', tokenCreateRateLimiter, async (req, res) => {
|
|
|
114
31
|
}
|
|
115
32
|
res.status(201).json(result.data);
|
|
116
33
|
});
|
|
117
|
-
/**
|
|
118
|
-
* @swagger
|
|
119
|
-
* /api/tokens/{id}:
|
|
120
|
-
* delete:
|
|
121
|
-
* summary: Revoke API token
|
|
122
|
-
* description: Revokes an API token. The token stops working immediately. Idempotent.
|
|
123
|
-
* tags: [API Tokens]
|
|
124
|
-
* security:
|
|
125
|
-
* - cookieAuth: []
|
|
126
|
-
* - bearerAuth: []
|
|
127
|
-
* - apiTokenAuth: []
|
|
128
|
-
* parameters:
|
|
129
|
-
* - in: path
|
|
130
|
-
* name: id
|
|
131
|
-
* required: true
|
|
132
|
-
* schema:
|
|
133
|
-
* type: string
|
|
134
|
-
* responses:
|
|
135
|
-
* 200:
|
|
136
|
-
* description: Token revoked
|
|
137
|
-
* 400:
|
|
138
|
-
* description: Token not found
|
|
139
|
-
* 401:
|
|
140
|
-
* description: Unauthorized
|
|
141
|
-
*/
|
|
142
34
|
router.delete('/:id', async (req, res) => {
|
|
143
35
|
const authReq = req;
|
|
144
36
|
const userId = authReq.user.id;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tokens.js","sourceRoot":"","sources":["../../src/routes/tokens.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAe,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACjE,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AACnE,OAAO,KAAK,SAAS,MAAM,2BAA2B,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC;AACxB,MAAM,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC;AAE1B
|
|
1
|
+
{"version":3,"file":"tokens.js","sourceRoot":"","sources":["../../src/routes/tokens.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"users.d.ts","sourceRoot":"","sources":["../../src/routes/users.ts"],"names":[],"mappings":"AAQA,QAAA,MAAM,MAAM,4CAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"users.d.ts","sourceRoot":"","sources":["../../src/routes/users.ts"],"names":[],"mappings":"AAQA,QAAA,MAAM,MAAM,4CAAW,CAAC;AAsIxB,eAAe,MAAM,CAAC"}
|
|
@@ -7,43 +7,6 @@ import crypto from 'crypto';
|
|
|
7
7
|
import { sendEmailVerificationEmail } from '../utils/email.js';
|
|
8
8
|
const router = Router();
|
|
9
9
|
router.use(requireAuth());
|
|
10
|
-
/**
|
|
11
|
-
* @swagger
|
|
12
|
-
* /api/users/me:
|
|
13
|
-
* get:
|
|
14
|
-
* summary: Get current user profile
|
|
15
|
-
* description: Returns the authenticated user's profile information
|
|
16
|
-
* tags: [Users]
|
|
17
|
-
* security:
|
|
18
|
-
* - cookieAuth: []
|
|
19
|
-
* - bearerAuth: []
|
|
20
|
-
* responses:
|
|
21
|
-
* 200:
|
|
22
|
-
* description: User profile
|
|
23
|
-
* content:
|
|
24
|
-
* application/json:
|
|
25
|
-
* schema:
|
|
26
|
-
* type: object
|
|
27
|
-
* properties:
|
|
28
|
-
* id:
|
|
29
|
-
* type: string
|
|
30
|
-
* email:
|
|
31
|
-
* type: string
|
|
32
|
-
* name:
|
|
33
|
-
* type: string
|
|
34
|
-
* user_key:
|
|
35
|
-
* type: string
|
|
36
|
-
* is_admin:
|
|
37
|
-
* type: boolean
|
|
38
|
-
* language:
|
|
39
|
-
* type: string
|
|
40
|
-
* example: "en"
|
|
41
|
-
* theme:
|
|
42
|
-
* type: string
|
|
43
|
-
* example: "auto"
|
|
44
|
-
* 401:
|
|
45
|
-
* description: Unauthorized
|
|
46
|
-
*/
|
|
47
10
|
// Get current user profile
|
|
48
11
|
router.get('/me', async (req, res) => {
|
|
49
12
|
const authReq = req;
|
|
@@ -56,50 +19,6 @@ router.get('/me', async (req, res) => {
|
|
|
56
19
|
res.status(500).json({ error: error.message });
|
|
57
20
|
}
|
|
58
21
|
});
|
|
59
|
-
/**
|
|
60
|
-
* @swagger
|
|
61
|
-
* /api/users/me:
|
|
62
|
-
* put:
|
|
63
|
-
* summary: Update user settings
|
|
64
|
-
* description: Updates the authenticated user's profile information including email, name, language, and theme preferences
|
|
65
|
-
* tags: [Users]
|
|
66
|
-
* security:
|
|
67
|
-
* - cookieAuth: []
|
|
68
|
-
* - bearerAuth: []
|
|
69
|
-
* requestBody:
|
|
70
|
-
* required: true
|
|
71
|
-
* content:
|
|
72
|
-
* application/json:
|
|
73
|
-
* schema:
|
|
74
|
-
* type: object
|
|
75
|
-
* properties:
|
|
76
|
-
* email:
|
|
77
|
-
* type: string
|
|
78
|
-
* format: email
|
|
79
|
-
* example: "updated@example.com"
|
|
80
|
-
* description: User's email address (must be unique)
|
|
81
|
-
* name:
|
|
82
|
-
* type: string
|
|
83
|
-
* example: "Updated Name"
|
|
84
|
-
* description: User's display name
|
|
85
|
-
* language:
|
|
86
|
-
* type: string
|
|
87
|
-
* enum: [en, de, fr]
|
|
88
|
-
* example: "en"
|
|
89
|
-
* description: User's preferred language
|
|
90
|
-
* theme:
|
|
91
|
-
* type: string
|
|
92
|
-
* enum: [light, dark, auto]
|
|
93
|
-
* example: "auto"
|
|
94
|
-
* description: User's preferred theme
|
|
95
|
-
* responses:
|
|
96
|
-
* 200:
|
|
97
|
-
* description: User settings updated successfully
|
|
98
|
-
* 400:
|
|
99
|
-
* description: Invalid input or email already exists
|
|
100
|
-
* 401:
|
|
101
|
-
* description: Unauthorized
|
|
102
|
-
*/
|
|
103
22
|
// Update user settings
|
|
104
23
|
router.put('/me', async (req, res) => {
|
|
105
24
|
const authReq = req;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"users.js","sourceRoot":"","sources":["../../src/routes/users.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAe,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACvG,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,MAAM,CAAC;AACpC,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,0BAA0B,EAAE,MAAM,mBAAmB,CAAC;AAE/D,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC;AACxB,MAAM,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC;AAE1B
|
|
1
|
+
{"version":3,"file":"users.js","sourceRoot":"","sources":["../../src/routes/users.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,23 +1,25 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* AI suggestions feature flag logic
|
|
2
|
+
* AI suggestions feature flag logic.
|
|
3
|
+
* When OPENAI_API_KEY env is set, API key and model come from env (global); ai_enabled remains per-tenant in system_config.
|
|
3
4
|
*/
|
|
4
5
|
/**
|
|
5
6
|
* Check if AI feature is available (org/plan/config allows it).
|
|
6
7
|
* Does not consider user-level ai_suggestions_enabled.
|
|
8
|
+
* When OPENAI_API_KEY is set, returns tenant's ai_enabled from system_config; else checks ai_enabled + ai_api_key from system_config (tenant-scoped).
|
|
7
9
|
*/
|
|
8
|
-
export declare function isAIFeatureAvailable(userId: string): Promise<boolean>;
|
|
10
|
+
export declare function isAIFeatureAvailable(userId: string, tenantId: string): Promise<boolean>;
|
|
9
11
|
/**
|
|
10
12
|
* Check if AI suggestions are enabled for the user.
|
|
11
13
|
* Returns false if not configured or user opted out.
|
|
12
14
|
*/
|
|
13
|
-
export declare function isAISuggestionsEnabled(userId: string): Promise<boolean>;
|
|
15
|
+
export declare function isAISuggestionsEnabled(userId: string, tenantId: string): Promise<boolean>;
|
|
14
16
|
/**
|
|
15
17
|
* Get AI API key for making requests.
|
|
16
|
-
*
|
|
18
|
+
* When OPENAI_API_KEY env is set, returns it; else reads from system_config (tenant-scoped) and decrypts when needed.
|
|
17
19
|
*/
|
|
18
|
-
export declare function getAIApiKey(): Promise<string | null>;
|
|
20
|
+
export declare function getAIApiKey(tenantId: string): Promise<string | null>;
|
|
19
21
|
/**
|
|
20
|
-
* Get AI model from config. Default gpt-4o-mini.
|
|
22
|
+
* Get AI model from config. When AI_SUGGESTIONS_MODEL env is set, returns it; else reads from system_config (tenant-scoped). Default gpt-4o-mini.
|
|
21
23
|
*/
|
|
22
|
-
export declare function getAIModel(): Promise<string>;
|
|
24
|
+
export declare function getAIModel(tenantId: string): Promise<string>;
|
|
23
25
|
//# sourceMappingURL=ai-feature.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-feature.d.ts","sourceRoot":"","sources":["../../src/utils/ai-feature.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"ai-feature.d.ts","sourceRoot":"","sources":["../../src/utils/ai-feature.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH;;;;GAIG;AACH,wBAAsB,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAkB7F;AAED;;;GAGG;AACH,wBAAsB,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAgC/F;AAED;;;GAGG;AACH,wBAAsB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAiB1E;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAOlE"}
|
|
@@ -1,43 +1,57 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* AI suggestions feature flag logic
|
|
2
|
+
* AI suggestions feature flag logic.
|
|
3
|
+
* When OPENAI_API_KEY env is set, API key and model come from env (global); ai_enabled remains per-tenant in system_config.
|
|
3
4
|
*/
|
|
4
5
|
import { queryOne } from '../db/index.js';
|
|
6
|
+
const ENV_API_KEY = (process.env.OPENAI_API_KEY ?? '').trim();
|
|
7
|
+
const ENV_MODEL = (process.env.AI_SUGGESTIONS_MODEL ?? '').trim();
|
|
5
8
|
/**
|
|
6
9
|
* Check if AI feature is available (org/plan/config allows it).
|
|
7
10
|
* Does not consider user-level ai_suggestions_enabled.
|
|
11
|
+
* When OPENAI_API_KEY is set, returns tenant's ai_enabled from system_config; else checks ai_enabled + ai_api_key from system_config (tenant-scoped).
|
|
8
12
|
*/
|
|
9
|
-
export async function isAIFeatureAvailable(userId) {
|
|
10
|
-
|
|
13
|
+
export async function isAIFeatureAvailable(userId, tenantId) {
|
|
14
|
+
if (ENV_API_KEY) {
|
|
15
|
+
const aiEnabled = await queryOne('SELECT value FROM system_config WHERE key = ? AND tenant_id = ?', ['ai_enabled', tenantId]);
|
|
16
|
+
return !!(aiEnabled && aiEnabled.value === 'true');
|
|
17
|
+
}
|
|
18
|
+
const aiEnabled = await queryOne('SELECT value FROM system_config WHERE key = ? AND tenant_id = ?', ['ai_enabled', tenantId]);
|
|
11
19
|
if (!aiEnabled || aiEnabled.value !== 'true')
|
|
12
20
|
return false;
|
|
13
|
-
const aiApiKey = await queryOne('SELECT value FROM system_config WHERE key = ?', ['ai_api_key']);
|
|
21
|
+
const aiApiKey = await queryOne('SELECT value FROM system_config WHERE key = ? AND tenant_id = ?', ['ai_api_key', tenantId]);
|
|
14
22
|
return !!(aiApiKey && aiApiKey.value);
|
|
15
23
|
}
|
|
16
24
|
/**
|
|
17
25
|
* Check if AI suggestions are enabled for the user.
|
|
18
26
|
* Returns false if not configured or user opted out.
|
|
19
27
|
*/
|
|
20
|
-
export async function isAISuggestionsEnabled(userId) {
|
|
28
|
+
export async function isAISuggestionsEnabled(userId, tenantId) {
|
|
21
29
|
const userRow = await queryOne('SELECT ai_suggestions_enabled FROM users WHERE id = ?', [userId]);
|
|
22
30
|
const userEnabled = userRow
|
|
23
31
|
? userRow.ai_suggestions_enabled !== 0 && userRow.ai_suggestions_enabled !== false
|
|
24
32
|
: true;
|
|
25
33
|
if (!userEnabled)
|
|
26
34
|
return false;
|
|
27
|
-
|
|
35
|
+
if (ENV_API_KEY) {
|
|
36
|
+
const aiEnabled = await queryOne('SELECT value FROM system_config WHERE key = ? AND tenant_id = ?', ['ai_enabled', tenantId]);
|
|
37
|
+
return !!(aiEnabled && aiEnabled.value === 'true');
|
|
38
|
+
}
|
|
39
|
+
const aiEnabled = await queryOne('SELECT value FROM system_config WHERE key = ? AND tenant_id = ?', ['ai_enabled', tenantId]);
|
|
28
40
|
if (!aiEnabled || aiEnabled.value !== 'true')
|
|
29
41
|
return false;
|
|
30
|
-
const aiApiKey = await queryOne('SELECT value FROM system_config WHERE key = ?', ['ai_api_key']);
|
|
42
|
+
const aiApiKey = await queryOne('SELECT value FROM system_config WHERE key = ? AND tenant_id = ?', ['ai_api_key', tenantId]);
|
|
31
43
|
if (!aiApiKey || !aiApiKey.value)
|
|
32
44
|
return false;
|
|
33
45
|
return true;
|
|
34
46
|
}
|
|
35
47
|
/**
|
|
36
48
|
* Get AI API key for making requests.
|
|
37
|
-
*
|
|
49
|
+
* When OPENAI_API_KEY env is set, returns it; else reads from system_config (tenant-scoped) and decrypts when needed.
|
|
38
50
|
*/
|
|
39
|
-
export async function getAIApiKey() {
|
|
40
|
-
|
|
51
|
+
export async function getAIApiKey(tenantId) {
|
|
52
|
+
if (ENV_API_KEY)
|
|
53
|
+
return ENV_API_KEY;
|
|
54
|
+
const row = await queryOne('SELECT value FROM system_config WHERE key = ? AND tenant_id = ?', ['ai_api_key', tenantId]);
|
|
41
55
|
if (!row || !row.value)
|
|
42
56
|
return null;
|
|
43
57
|
const raw = row.value;
|
|
@@ -53,10 +67,12 @@ export async function getAIApiKey() {
|
|
|
53
67
|
}
|
|
54
68
|
}
|
|
55
69
|
/**
|
|
56
|
-
* Get AI model from config. Default gpt-4o-mini.
|
|
70
|
+
* Get AI model from config. When AI_SUGGESTIONS_MODEL env is set, returns it; else reads from system_config (tenant-scoped). Default gpt-4o-mini.
|
|
57
71
|
*/
|
|
58
|
-
export async function getAIModel() {
|
|
59
|
-
|
|
72
|
+
export async function getAIModel(tenantId) {
|
|
73
|
+
if (ENV_MODEL)
|
|
74
|
+
return ENV_MODEL;
|
|
75
|
+
const row = await queryOne('SELECT value FROM system_config WHERE key = ? AND tenant_id = ?', ['ai_model', tenantId]);
|
|
60
76
|
return (row && row.value) ? String(row.value) : 'gpt-4o-mini';
|
|
61
77
|
}
|
|
62
78
|
//# sourceMappingURL=ai-feature.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-feature.js","sourceRoot":"","sources":["../../src/utils/ai-feature.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"ai-feature.js","sourceRoot":"","sources":["../../src/utils/ai-feature.ts"],"names":[],"mappings":"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"}
|
package/frontend/src/App.tsx
CHANGED
|
@@ -238,9 +238,11 @@ export interface AppProps {
|
|
|
238
238
|
skipSetupFlow?: boolean;
|
|
239
239
|
/** When true, hide Admin OIDC and SMTP/Settings (e.g. cloud uses Postmark and global OIDC). */
|
|
240
240
|
hideAdminOidcAndSmtp?: boolean;
|
|
241
|
+
/** When true, Admin AI page shows only the enable/disable toggle (e.g. cloud uses env for provider/model/key). */
|
|
242
|
+
adminAiOnlyToggle?: boolean;
|
|
241
243
|
}
|
|
242
244
|
|
|
243
|
-
function App({ basePath, apiBaseUrl, routerBasename, skipSetupFlow, hideAdminOidcAndSmtp }: AppProps = {}) {
|
|
245
|
+
function App({ basePath, apiBaseUrl, routerBasename, skipSetupFlow, hideAdminOidcAndSmtp, adminAiOnlyToggle }: AppProps = {}) {
|
|
244
246
|
const appRootPath = basePath === '/' || !basePath ? '/' : basePath;
|
|
245
247
|
const pathPrefixForLinks = routerBasename !== undefined ? '' : (basePath ?? '');
|
|
246
248
|
const content = (
|
|
@@ -254,7 +256,7 @@ function App({ basePath, apiBaseUrl, routerBasename, skipSetupFlow, hideAdminOid
|
|
|
254
256
|
);
|
|
255
257
|
return (
|
|
256
258
|
<AppErrorBoundary>
|
|
257
|
-
<AppConfigProvider appBasePath={basePath} apiBaseUrl={apiBaseUrl} appRootPath={appRootPath} skipSetupFlow={skipSetupFlow} pathPrefixForLinks={pathPrefixForLinks} hideAdminOidcAndSmtp={hideAdminOidcAndSmtp}>
|
|
259
|
+
<AppConfigProvider appBasePath={basePath} apiBaseUrl={apiBaseUrl} appRootPath={appRootPath} skipSetupFlow={skipSetupFlow} pathPrefixForLinks={pathPrefixForLinks} hideAdminOidcAndSmtp={hideAdminOidcAndSmtp} adminAiOnlyToggle={adminAiOnlyToggle}>
|
|
258
260
|
{routerBasename !== undefined ? (
|
|
259
261
|
content
|
|
260
262
|
) : (
|