@promptbook/cli 0.112.0-100 → 0.112.0-102
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/apps/agents-server/README.md +6 -0
- package/apps/agents-server/package.json +1 -1
- package/apps/agents-server/scripts/prerender-homepage.js +76 -1
- package/apps/agents-server/src/app/actions.ts +0 -6
- package/apps/agents-server/src/app/admin/about/page.tsx +1 -1
- package/apps/agents-server/src/app/admin/login-methods/shibboleth/page.tsx +365 -0
- package/apps/agents-server/src/app/admin/servers/ServersRegistryTable.tsx +3 -3
- package/apps/agents-server/src/app/admin/update/UpdateClient.tsx +12 -3
- package/apps/agents-server/src/app/admin/usage/UsageClientTimelineChart.tsx +1 -1
- package/apps/agents-server/src/app/admin/users/[userId]/UserDetailClient.tsx +21 -14
- package/apps/agents-server/src/app/agents/[agentName]/chat/AgentChatPageLayout.tsx +2 -2
- package/apps/agents-server/src/app/agents/[agentName]/chat/AgentChatSidebarDefault.tsx +11 -7
- package/apps/agents-server/src/app/api/admin/cli-access/route.ts +27 -123
- package/apps/agents-server/src/app/api/admin/code-runners/authentication/route.ts +33 -125
- package/apps/agents-server/src/app/api/auth/login/route.ts +0 -10
- package/apps/agents-server/src/app/api/auth/shibboleth/acs/route.ts +77 -57
- package/apps/agents-server/src/app/api/auth/shibboleth/login/route.ts +57 -33
- package/apps/agents-server/src/app/api/auth/shibboleth/metadata/route.ts +4 -29
- package/apps/agents-server/src/app/api/auth/shibboleth/status/route.ts +17 -0
- package/apps/agents-server/src/app/api/upload/route.ts +230 -18
- package/apps/agents-server/src/app/api/users/[username]/route.ts +1 -1
- package/apps/agents-server/src/app/api/users/route.ts +5 -5
- package/apps/agents-server/src/app/dashboard/page.tsx +1 -1
- package/apps/agents-server/src/app/docs/[docId]/page.tsx +1 -1
- package/apps/agents-server/src/app/docs/page.tsx +1 -1
- package/apps/agents-server/src/app/globals.css +100 -0
- package/apps/agents-server/src/app/layout.tsx +7 -0
- package/apps/agents-server/src/app/recycle-bin/page.tsx +1 -1
- package/apps/agents-server/src/app/system/settings/KeybindingsSettingsClient.tsx +13 -7
- package/apps/agents-server/src/components/AdminTerminal/useAdminTerminalSession.ts +29 -1
- package/apps/agents-server/src/components/AgentProfile/AgentProfile.tsx +3 -3
- package/apps/agents-server/src/components/AgentProfile/AgentProfileImage.tsx +8 -2
- package/apps/agents-server/src/components/DocsToolbar/DocsToolbar.tsx +4 -4
- package/apps/agents-server/src/components/DocumentationContent/DocumentationContent.tsx +9 -9
- package/apps/agents-server/src/components/Footer/Footer.tsx +7 -7
- package/apps/agents-server/src/components/Header/Header.tsx +24 -4
- package/apps/agents-server/src/components/Header/HeaderTypes.ts +6 -0
- package/apps/agents-server/src/components/Header/buildHeaderSystemMenuItems.ts +51 -1
- package/apps/agents-server/src/components/Homepage/Card.tsx +1 -1
- package/apps/agents-server/src/components/Homepage/Section.tsx +3 -1
- package/apps/agents-server/src/components/LayoutWrapper/LayoutWrapper.tsx +12 -1
- package/apps/agents-server/src/components/LoginForm/LoginForm.tsx +100 -149
- package/apps/agents-server/src/components/Skeleton/ConsolePageLoadingSkeleton.tsx +1 -1
- package/apps/agents-server/src/components/Skeleton/DocumentationRouteLoadingSkeleton.tsx +1 -1
- package/apps/agents-server/src/components/Skeleton/HomepageLoadingSkeleton.tsx +1 -1
- package/apps/agents-server/src/components/UsersList/UsersList.tsx +20 -4
- package/apps/agents-server/src/components/UsersList/useUsersAdmin.ts +3 -0
- package/apps/agents-server/src/constants/shibbolethAuth.ts +139 -0
- package/apps/agents-server/src/database/metadataDefaults.ts +54 -80
- package/apps/agents-server/src/database/migrate.ts +30 -1
- package/apps/agents-server/src/database/migrations/2026-06-0100-shibboleth-auth.sql +136 -0
- package/apps/agents-server/src/database/sqlite/$provideLocalSqliteSupabase.ts +88 -36
- package/apps/agents-server/src/languages/ServerTranslationKeys.ts +4 -2
- package/apps/agents-server/src/languages/translations/czech.yaml +4 -2
- package/apps/agents-server/src/languages/translations/english.yaml +5 -3
- package/apps/agents-server/src/tools/$provideCdnForServer.ts +69 -23
- package/apps/agents-server/src/utils/cdn/classes/DigitalOceanSpaces.ts +54 -6
- package/apps/agents-server/src/utils/cdn/classes/TrackedFilesStorage.ts +4 -6
- package/apps/agents-server/src/utils/cdn/resolveCdnStorageProvider.ts +40 -0
- package/apps/agents-server/src/utils/chatExport/renderHtmlToPdfOnServer.ts +11 -0
- package/apps/agents-server/src/utils/createAdminTerminalRouteHandlers.ts +264 -0
- package/apps/agents-server/src/utils/shareTargetPayloads.ts +11 -10
- package/apps/agents-server/src/utils/shibbolethAuthentication.ts +729 -621
- package/apps/agents-server/src/utils/upload/createBookEditorUploadHandler.ts +137 -19
- package/esm/index.es.js +1 -1
- package/esm/src/book-components/Chat/MarkdownContent/MarkdownContent.d.ts +1 -0
- package/esm/src/version.d.ts +1 -1
- package/package.json +2 -2
- package/src/book-components/Chat/MarkdownContent/MarkdownContent.tsx +65 -4
- package/src/other/templates/getTemplatesPipelineCollection.ts +877 -689
- package/src/version.ts +2 -2
- package/src/versions.txt +2 -0
- package/umd/index.umd.js +1 -1
- package/umd/src/book-components/Chat/MarkdownContent/MarkdownContent.d.ts +1 -0
- package/umd/src/version.d.ts +1 -1
- package/apps/agents-server/src/app/api/auth/methods/route.ts +0 -44
- package/apps/agents-server/src/constants/authenticationMethods.ts +0 -74
- package/apps/agents-server/src/constants/shibbolethAuthentication.ts +0 -107
|
@@ -2,11 +2,6 @@ import { spaceTrim } from 'spacetrim';
|
|
|
2
2
|
import { CORE_AGENTS_SERVER } from '../../../../servers';
|
|
3
3
|
import { DEFAULT_THINKING_MESSAGES } from '../../../../src/utils/DEFAULT_THINKING_MESSAGES';
|
|
4
4
|
import { ANALYTICS_METADATA_KEYS, getAnalyticsMetadataDefinition } from '../constants/analyticsMetadata';
|
|
5
|
-
import {
|
|
6
|
-
AUTHENTICATION_METHOD_VALUES,
|
|
7
|
-
AUTHENTICATION_METHODS_METADATA_KEY,
|
|
8
|
-
DEFAULT_AUTHENTICATION_METHODS_METADATA_VALUE,
|
|
9
|
-
} from '../constants/authenticationMethods';
|
|
10
5
|
import {
|
|
11
6
|
DEFAULT_FEDERATED_AGENT_IMPORT_RETRY_DELAY_MS,
|
|
12
7
|
FEDERATED_AGENT_IMPORT_RETRY_DELAY_MS_METADATA_KEY,
|
|
@@ -25,24 +20,23 @@ import {
|
|
|
25
20
|
import { DEFAULT_THEME_METADATA_KEY, DEFAULT_THEME_MODE, THEME_MODE_OPTIONS } from '../constants/themeMode';
|
|
26
21
|
import { DEFAULT_NAME_POOL, NAME_POOL_METADATA_KEY, NAME_POOL_OPTIONS } from '../constants/namePool';
|
|
27
22
|
import { NEW_AGENT_WIZZARD_METADATA_KEY, NEW_AGENT_WIZZARD_OPTIONS } from '../constants/newAgentWizard';
|
|
23
|
+
import {
|
|
24
|
+
DEFAULT_SHIBBOLETH_DISPLAY_NAME_ATTRIBUTE_NAMES,
|
|
25
|
+
DEFAULT_SHIBBOLETH_EMAIL_ATTRIBUTE_NAMES,
|
|
26
|
+
DEFAULT_SHIBBOLETH_UNSTRUCTURED_NAME_ATTRIBUTE_NAMES,
|
|
27
|
+
IS_SHIBBOLETH_AUTH_ACTIVE_METADATA_KEY,
|
|
28
|
+
SHIBBOLETH_DISPLAY_NAME_ATTRIBUTE_NAMES_METADATA_KEY,
|
|
29
|
+
SHIBBOLETH_EMAIL_ATTRIBUTE_NAMES_METADATA_KEY,
|
|
30
|
+
SHIBBOLETH_IDENTITY_PROVIDER_METADATA_URL_METADATA_KEY,
|
|
31
|
+
SHIBBOLETH_IDENTITY_PROVIDER_METADATA_XML_METADATA_KEY,
|
|
32
|
+
SHIBBOLETH_SERVICE_PROVIDER_ENTITY_ID_METADATA_KEY,
|
|
33
|
+
SHIBBOLETH_UNSTRUCTURED_NAME_ATTRIBUTE_NAMES_METADATA_KEY,
|
|
34
|
+
} from '../constants/shibbolethAuth';
|
|
28
35
|
import {
|
|
29
36
|
DEFAULT_SERVER_LIMIT_VALUES,
|
|
30
37
|
MAX_FILE_UPLOAD_SIZE_MB_METADATA_KEY,
|
|
31
38
|
SERVER_LIMIT_KEYS,
|
|
32
39
|
} from '../constants/serverLimits';
|
|
33
|
-
import {
|
|
34
|
-
DEFAULT_SHIBBOLETH_PROVIDER_LABEL,
|
|
35
|
-
DEFAULT_SHIBBOLETH_USERNAME_ATTRIBUTE,
|
|
36
|
-
SHIBBOLETH_AUTO_CREATE_USERS_METADATA_KEY,
|
|
37
|
-
SHIBBOLETH_CALLBACK_URL_METADATA_KEY,
|
|
38
|
-
SHIBBOLETH_ENTITY_ID_METADATA_KEY,
|
|
39
|
-
SHIBBOLETH_IDP_CERTIFICATE_METADATA_KEY,
|
|
40
|
-
SHIBBOLETH_IDP_ENTRYPOINT_METADATA_KEY,
|
|
41
|
-
SHIBBOLETH_IDP_ISSUER_METADATA_KEY,
|
|
42
|
-
SHIBBOLETH_IDP_METADATA_URL_METADATA_KEY,
|
|
43
|
-
SHIBBOLETH_PROVIDER_LABEL_METADATA_KEY,
|
|
44
|
-
SHIBBOLETH_USERNAME_ATTRIBUTE_METADATA_KEY,
|
|
45
|
-
} from '../constants/shibbolethAuthentication';
|
|
46
40
|
import { DEFAULT_TOOL_USAGE_LIMITS, TOOL_USAGE_LIMITS_METADATA_KEY } from '../constants/toolUsageLimits';
|
|
47
41
|
import {
|
|
48
42
|
IS_SERVER_LANGUAGE_ENFORCED_METADATA_KEY,
|
|
@@ -163,6 +157,48 @@ export const metadataDefaults = [
|
|
|
163
157
|
type: 'TEXT_SINGLE_LINE',
|
|
164
158
|
options: SERVER_VISIBILITY_OPTIONS,
|
|
165
159
|
},
|
|
160
|
+
{
|
|
161
|
+
key: IS_SHIBBOLETH_AUTH_ACTIVE_METADATA_KEY,
|
|
162
|
+
value: 'false',
|
|
163
|
+
note: 'Enable Shibboleth authentication alongside standard username/password login.',
|
|
164
|
+
type: 'BOOLEAN',
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
key: SHIBBOLETH_IDENTITY_PROVIDER_METADATA_URL_METADATA_KEY,
|
|
168
|
+
value: '',
|
|
169
|
+
note: 'URL of the Shibboleth Identity Provider metadata XML. For Silesian University this is https://idp-cro.slu.cz/idp/shibboleth.',
|
|
170
|
+
type: 'TEXT_SINGLE_LINE',
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
key: SHIBBOLETH_IDENTITY_PROVIDER_METADATA_XML_METADATA_KEY,
|
|
174
|
+
value: '',
|
|
175
|
+
note: 'Optional pasted Shibboleth Identity Provider metadata XML. Used instead of SHIBBOLETH_IDP_METADATA_URL when filled.',
|
|
176
|
+
type: 'TEXT',
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
key: SHIBBOLETH_SERVICE_PROVIDER_ENTITY_ID_METADATA_KEY,
|
|
180
|
+
value: '',
|
|
181
|
+
note: 'Optional Service Provider entity ID override. When empty, Agents Server uses the generated Shibboleth metadata endpoint URL.',
|
|
182
|
+
type: 'TEXT_SINGLE_LINE',
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
key: SHIBBOLETH_EMAIL_ATTRIBUTE_NAMES_METADATA_KEY,
|
|
186
|
+
value: DEFAULT_SHIBBOLETH_EMAIL_ATTRIBUTE_NAMES,
|
|
187
|
+
note: 'Space-separated SAML attribute names accepted as the user email during Shibboleth login.',
|
|
188
|
+
type: 'TEXT_SINGLE_LINE',
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
key: SHIBBOLETH_DISPLAY_NAME_ATTRIBUTE_NAMES_METADATA_KEY,
|
|
192
|
+
value: DEFAULT_SHIBBOLETH_DISPLAY_NAME_ATTRIBUTE_NAMES,
|
|
193
|
+
note: 'Space-separated SAML attribute names accepted as the user display name during Shibboleth login.',
|
|
194
|
+
type: 'TEXT_SINGLE_LINE',
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
key: SHIBBOLETH_UNSTRUCTURED_NAME_ATTRIBUTE_NAMES_METADATA_KEY,
|
|
198
|
+
value: DEFAULT_SHIBBOLETH_UNSTRUCTURED_NAME_ATTRIBUTE_NAMES,
|
|
199
|
+
note: 'Space-separated SAML attribute names accepted as the institutional identifier during Shibboleth login.',
|
|
200
|
+
type: 'TEXT_SINGLE_LINE',
|
|
201
|
+
},
|
|
166
202
|
{
|
|
167
203
|
key: 'AGENT_NAMING',
|
|
168
204
|
value: 'Agent / Agents',
|
|
@@ -427,68 +463,6 @@ export const metadataDefaults = [
|
|
|
427
463
|
note: 'Administrator email address used for password reset and user registration requests.',
|
|
428
464
|
type: 'TEXT_SINGLE_LINE',
|
|
429
465
|
},
|
|
430
|
-
{
|
|
431
|
-
key: AUTHENTICATION_METHODS_METADATA_KEY,
|
|
432
|
-
value: DEFAULT_AUTHENTICATION_METHODS_METADATA_VALUE,
|
|
433
|
-
note: `Comma-separated login methods enabled on this server. Available values: ${AUTHENTICATION_METHOD_VALUES.join(
|
|
434
|
-
', ',
|
|
435
|
-
)}. Shibboleth is inactive unless SHIBBOLETH is included here.`,
|
|
436
|
-
type: 'TEXT_SINGLE_LINE',
|
|
437
|
-
},
|
|
438
|
-
{
|
|
439
|
-
key: SHIBBOLETH_IDP_METADATA_URL_METADATA_KEY,
|
|
440
|
-
value: '',
|
|
441
|
-
note: 'URL of the Shibboleth Identity Provider metadata XML. When set, the IdP SSO URL and signing certificates are loaded from this document.',
|
|
442
|
-
type: 'TEXT_SINGLE_LINE',
|
|
443
|
-
},
|
|
444
|
-
{
|
|
445
|
-
key: SHIBBOLETH_IDP_ENTRYPOINT_METADATA_KEY,
|
|
446
|
-
value: '',
|
|
447
|
-
note: 'Fallback Shibboleth Identity Provider SSO URL used when it cannot be loaded from metadata.',
|
|
448
|
-
type: 'TEXT_SINGLE_LINE',
|
|
449
|
-
},
|
|
450
|
-
{
|
|
451
|
-
key: SHIBBOLETH_IDP_CERTIFICATE_METADATA_KEY,
|
|
452
|
-
value: '',
|
|
453
|
-
note: 'Fallback Shibboleth IdP signing certificate in PEM or base64 form. Multiple certificates can be separated by blank lines.',
|
|
454
|
-
type: 'TEXT',
|
|
455
|
-
},
|
|
456
|
-
{
|
|
457
|
-
key: SHIBBOLETH_IDP_ISSUER_METADATA_KEY,
|
|
458
|
-
value: '',
|
|
459
|
-
note: 'Optional expected Shibboleth IdP entity ID. Leave empty to use the entityID from IdP metadata.',
|
|
460
|
-
type: 'TEXT_SINGLE_LINE',
|
|
461
|
-
},
|
|
462
|
-
{
|
|
463
|
-
key: SHIBBOLETH_ENTITY_ID_METADATA_KEY,
|
|
464
|
-
value: '',
|
|
465
|
-
note: 'Optional SAML Service Provider EntityID. Leave empty to use this server public URL plus /api/auth/shibboleth/metadata.',
|
|
466
|
-
type: 'TEXT_SINGLE_LINE',
|
|
467
|
-
},
|
|
468
|
-
{
|
|
469
|
-
key: SHIBBOLETH_CALLBACK_URL_METADATA_KEY,
|
|
470
|
-
value: '',
|
|
471
|
-
note: 'Optional SAML Assertion Consumer Service URL. Leave empty to use this server public URL plus /api/auth/shibboleth/acs.',
|
|
472
|
-
type: 'TEXT_SINGLE_LINE',
|
|
473
|
-
},
|
|
474
|
-
{
|
|
475
|
-
key: SHIBBOLETH_USERNAME_ATTRIBUTE_METADATA_KEY,
|
|
476
|
-
value: DEFAULT_SHIBBOLETH_USERNAME_ATTRIBUTE,
|
|
477
|
-
note: 'SAML attribute used as the Agents Server username. For Silesian University this is usually mail or unstructuredName.',
|
|
478
|
-
type: 'TEXT_SINGLE_LINE',
|
|
479
|
-
},
|
|
480
|
-
{
|
|
481
|
-
key: SHIBBOLETH_AUTO_CREATE_USERS_METADATA_KEY,
|
|
482
|
-
value: 'true',
|
|
483
|
-
note: 'Create a non-admin Agents Server user automatically after a valid Shibboleth login when no matching username exists.',
|
|
484
|
-
type: 'BOOLEAN',
|
|
485
|
-
},
|
|
486
|
-
{
|
|
487
|
-
key: SHIBBOLETH_PROVIDER_LABEL_METADATA_KEY,
|
|
488
|
-
value: DEFAULT_SHIBBOLETH_PROVIDER_LABEL,
|
|
489
|
-
note: 'User-facing label for the Shibboleth login button.',
|
|
490
|
-
type: 'TEXT_SINGLE_LINE',
|
|
491
|
-
},
|
|
492
466
|
{
|
|
493
467
|
key: DEFAULT_VISIBILITY_METADATA_KEY,
|
|
494
468
|
value: 'UNLISTED',
|
|
@@ -5,8 +5,14 @@ import {
|
|
|
5
5
|
resolveDatabaseMigrationRuntimeConfiguration,
|
|
6
6
|
runDatabaseMigrations,
|
|
7
7
|
} from './runDatabaseMigrations';
|
|
8
|
+
import { isAgentsServerSqliteMode } from './agentsServerDatabaseMode';
|
|
8
9
|
|
|
9
|
-
|
|
10
|
+
/**
|
|
11
|
+
* Environment variable pointing to the installed Agents Server `.env` file.
|
|
12
|
+
*/
|
|
13
|
+
const AGENTS_SERVER_ENV_FILE_ENV_NAME = 'PTBK_AGENTS_SERVER_ENV_FILE';
|
|
14
|
+
|
|
15
|
+
loadDatabaseMigrationEnvironment();
|
|
10
16
|
|
|
11
17
|
/**
|
|
12
18
|
* Runs manual migration command from CLI arguments.
|
|
@@ -14,6 +20,11 @@ dotenv.config();
|
|
|
14
20
|
async function migrate(): Promise<void> {
|
|
15
21
|
console.info(colors.bgBlue('🚀 Starting database migration'));
|
|
16
22
|
|
|
23
|
+
if (isAgentsServerSqliteMode()) {
|
|
24
|
+
console.info(colors.yellow('⏭️ Skipping PostgreSQL migrations because Agents Server uses local SQLite.'));
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
|
|
17
28
|
const runtimeConfiguration = await resolveDatabaseMigrationRuntimeConfiguration(console);
|
|
18
29
|
if (!runtimeConfiguration) {
|
|
19
30
|
return;
|
|
@@ -46,6 +57,24 @@ async function migrate(): Promise<void> {
|
|
|
46
57
|
}
|
|
47
58
|
}
|
|
48
59
|
|
|
60
|
+
/**
|
|
61
|
+
* Loads database migration environment variables.
|
|
62
|
+
*
|
|
63
|
+
* Self-update runs the migration command from the repository checkout, while
|
|
64
|
+
* the deployed Agents Server `.env` lives in the installation directory.
|
|
65
|
+
*/
|
|
66
|
+
function loadDatabaseMigrationEnvironment(): void {
|
|
67
|
+
const explicitEnvFilePath = process.env[AGENTS_SERVER_ENV_FILE_ENV_NAME]?.trim();
|
|
68
|
+
if (explicitEnvFilePath) {
|
|
69
|
+
const explicitLoadResult = dotenv.config({ path: explicitEnvFilePath });
|
|
70
|
+
if (!explicitLoadResult.error) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
dotenv.config();
|
|
76
|
+
}
|
|
77
|
+
|
|
49
78
|
/**
|
|
50
79
|
* Parses optional `--only` flag from CLI arguments.
|
|
51
80
|
*
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
ALTER TABLE "prefix_User"
|
|
2
|
+
ADD COLUMN IF NOT EXISTS "email" TEXT NULL,
|
|
3
|
+
ADD COLUMN IF NOT EXISTS "displayName" TEXT NULL,
|
|
4
|
+
ADD COLUMN IF NOT EXISTS "authenticationProvider" TEXT NOT NULL DEFAULT 'LOCAL';
|
|
5
|
+
|
|
6
|
+
COMMENT ON COLUMN "prefix_User"."email" IS 'Email address used for external authentication providers such as Shibboleth.';
|
|
7
|
+
COMMENT ON COLUMN "prefix_User"."displayName" IS 'Human-readable display name from external authentication providers.';
|
|
8
|
+
COMMENT ON COLUMN "prefix_User"."authenticationProvider" IS 'Primary authentication provider marker. Values include LOCAL, SHIBBOLETH, and LOCAL_AND_SHIBBOLETH.';
|
|
9
|
+
|
|
10
|
+
CREATE TABLE IF NOT EXISTS "prefix_ShibbolethUserIdentity" (
|
|
11
|
+
"id" BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
|
12
|
+
"createdAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(),
|
|
13
|
+
"updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(),
|
|
14
|
+
"userId" BIGINT NOT NULL,
|
|
15
|
+
"email" TEXT NOT NULL,
|
|
16
|
+
"displayName" TEXT NULL,
|
|
17
|
+
"nameId" TEXT NULL,
|
|
18
|
+
"nameIdFormat" TEXT NULL,
|
|
19
|
+
"unstructuredName" TEXT NULL,
|
|
20
|
+
"eduPersonPrincipalName" TEXT NULL,
|
|
21
|
+
"rawAttributes" JSONB NULL,
|
|
22
|
+
"lastLoggedInAt" TIMESTAMP WITH TIME ZONE NULL,
|
|
23
|
+
"loginCount" BIGINT NOT NULL DEFAULT 0
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
COMMENT ON TABLE "prefix_ShibbolethUserIdentity" IS 'Link between Agents Server users and Shibboleth identities.';
|
|
27
|
+
COMMENT ON COLUMN "prefix_ShibbolethUserIdentity"."rawAttributes" IS 'Raw SAML assertion profile attributes received from Shibboleth.';
|
|
28
|
+
|
|
29
|
+
CREATE UNIQUE INDEX IF NOT EXISTS "prefix_ShibbolethUserIdentity_userId_idx"
|
|
30
|
+
ON "prefix_ShibbolethUserIdentity" ("userId");
|
|
31
|
+
CREATE UNIQUE INDEX IF NOT EXISTS "prefix_ShibbolethUserIdentity_email_idx"
|
|
32
|
+
ON "prefix_ShibbolethUserIdentity" ("email");
|
|
33
|
+
CREATE UNIQUE INDEX IF NOT EXISTS "prefix_ShibbolethUserIdentity_nameId_idx"
|
|
34
|
+
ON "prefix_ShibbolethUserIdentity" ("nameId");
|
|
35
|
+
CREATE INDEX IF NOT EXISTS "prefix_ShibbolethUserIdentity_lastLoggedInAt_idx"
|
|
36
|
+
ON "prefix_ShibbolethUserIdentity" ("lastLoggedInAt" DESC);
|
|
37
|
+
|
|
38
|
+
ALTER TABLE "prefix_ShibbolethUserIdentity"
|
|
39
|
+
DROP CONSTRAINT IF EXISTS "prefix_ShibbolethUserIdentity_userId_fkey",
|
|
40
|
+
ADD CONSTRAINT "prefix_ShibbolethUserIdentity_userId_fkey"
|
|
41
|
+
FOREIGN KEY ("userId")
|
|
42
|
+
REFERENCES "prefix_User"("id")
|
|
43
|
+
ON DELETE CASCADE;
|
|
44
|
+
|
|
45
|
+
ALTER TABLE "prefix_ShibbolethUserIdentity" ENABLE ROW LEVEL SECURITY;
|
|
46
|
+
|
|
47
|
+
CREATE TABLE IF NOT EXISTS "prefix_ShibbolethAuthenticationAttempt" (
|
|
48
|
+
"id" BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
|
49
|
+
"createdAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(),
|
|
50
|
+
"stage" TEXT NOT NULL,
|
|
51
|
+
"status" TEXT NOT NULL,
|
|
52
|
+
"userId" BIGINT NULL,
|
|
53
|
+
"email" TEXT NULL,
|
|
54
|
+
"displayName" TEXT NULL,
|
|
55
|
+
"nameId" TEXT NULL,
|
|
56
|
+
"relayState" TEXT NULL,
|
|
57
|
+
"ip" TEXT NULL,
|
|
58
|
+
"userAgent" TEXT NULL,
|
|
59
|
+
"errorMessage" TEXT NULL,
|
|
60
|
+
"rawAttributes" JSONB NULL
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
COMMENT ON TABLE "prefix_ShibbolethAuthenticationAttempt" IS 'Audit log of Shibboleth authentication attempts.';
|
|
64
|
+
COMMENT ON COLUMN "prefix_ShibbolethAuthenticationAttempt"."stage" IS 'Authentication process stage such as LOGIN_REQUEST or ASSERTION_CONSUMER_SERVICE.';
|
|
65
|
+
COMMENT ON COLUMN "prefix_ShibbolethAuthenticationAttempt"."status" IS 'Attempt result such as STARTED, REDIRECTED, SUCCESS, FAILED, or REJECTED.';
|
|
66
|
+
COMMENT ON COLUMN "prefix_ShibbolethAuthenticationAttempt"."rawAttributes" IS 'Raw SAML assertion profile attributes when available.';
|
|
67
|
+
|
|
68
|
+
CREATE INDEX IF NOT EXISTS "prefix_ShibbolethAuthenticationAttempt_createdAt_idx"
|
|
69
|
+
ON "prefix_ShibbolethAuthenticationAttempt" ("createdAt" DESC);
|
|
70
|
+
CREATE INDEX IF NOT EXISTS "prefix_ShibbolethAuthenticationAttempt_email_idx"
|
|
71
|
+
ON "prefix_ShibbolethAuthenticationAttempt" ("email");
|
|
72
|
+
|
|
73
|
+
ALTER TABLE "prefix_ShibbolethAuthenticationAttempt"
|
|
74
|
+
DROP CONSTRAINT IF EXISTS "prefix_ShibbolethAuthenticationAttempt_userId_fkey",
|
|
75
|
+
ADD CONSTRAINT "prefix_ShibbolethAuthenticationAttempt_userId_fkey"
|
|
76
|
+
FOREIGN KEY ("userId")
|
|
77
|
+
REFERENCES "prefix_User"("id")
|
|
78
|
+
ON DELETE SET NULL;
|
|
79
|
+
|
|
80
|
+
ALTER TABLE "prefix_ShibbolethAuthenticationAttempt" ENABLE ROW LEVEL SECURITY;
|
|
81
|
+
|
|
82
|
+
INSERT INTO "prefix_Metadata" ("key", "value", "note", "createdAt", "updatedAt")
|
|
83
|
+
SELECT 'IS_SHIBBOLETH_AUTH_ACTIVE',
|
|
84
|
+
'false',
|
|
85
|
+
'Enable Shibboleth authentication alongside standard username/password login.',
|
|
86
|
+
NOW(),
|
|
87
|
+
NOW()
|
|
88
|
+
WHERE NOT EXISTS (SELECT 1 FROM "prefix_Metadata" WHERE "key" = 'IS_SHIBBOLETH_AUTH_ACTIVE');
|
|
89
|
+
|
|
90
|
+
INSERT INTO "prefix_Metadata" ("key", "value", "note", "createdAt", "updatedAt")
|
|
91
|
+
SELECT 'SHIBBOLETH_IDP_METADATA_URL',
|
|
92
|
+
'',
|
|
93
|
+
'URL of the Shibboleth Identity Provider metadata XML. For Silesian University this is https://idp-cro.slu.cz/idp/shibboleth.',
|
|
94
|
+
NOW(),
|
|
95
|
+
NOW()
|
|
96
|
+
WHERE NOT EXISTS (SELECT 1 FROM "prefix_Metadata" WHERE "key" = 'SHIBBOLETH_IDP_METADATA_URL');
|
|
97
|
+
|
|
98
|
+
INSERT INTO "prefix_Metadata" ("key", "value", "note", "createdAt", "updatedAt")
|
|
99
|
+
SELECT 'SHIBBOLETH_IDP_METADATA_XML',
|
|
100
|
+
'',
|
|
101
|
+
'Optional pasted Shibboleth Identity Provider metadata XML. Used instead of SHIBBOLETH_IDP_METADATA_URL when filled.',
|
|
102
|
+
NOW(),
|
|
103
|
+
NOW()
|
|
104
|
+
WHERE NOT EXISTS (SELECT 1 FROM "prefix_Metadata" WHERE "key" = 'SHIBBOLETH_IDP_METADATA_XML');
|
|
105
|
+
|
|
106
|
+
INSERT INTO "prefix_Metadata" ("key", "value", "note", "createdAt", "updatedAt")
|
|
107
|
+
SELECT 'SHIBBOLETH_SP_ENTITY_ID',
|
|
108
|
+
'',
|
|
109
|
+
'Optional Service Provider entity ID override. When empty, Agents Server uses the generated Shibboleth metadata endpoint URL.',
|
|
110
|
+
NOW(),
|
|
111
|
+
NOW()
|
|
112
|
+
WHERE NOT EXISTS (SELECT 1 FROM "prefix_Metadata" WHERE "key" = 'SHIBBOLETH_SP_ENTITY_ID');
|
|
113
|
+
|
|
114
|
+
INSERT INTO "prefix_Metadata" ("key", "value", "note", "createdAt", "updatedAt")
|
|
115
|
+
SELECT 'SHIBBOLETH_EMAIL_ATTRIBUTE_NAMES',
|
|
116
|
+
'mail email urn:oid:0.9.2342.19200300.100.1.3',
|
|
117
|
+
'Space-separated SAML attribute names accepted as the user email during Shibboleth login.',
|
|
118
|
+
NOW(),
|
|
119
|
+
NOW()
|
|
120
|
+
WHERE NOT EXISTS (SELECT 1 FROM "prefix_Metadata" WHERE "key" = 'SHIBBOLETH_EMAIL_ATTRIBUTE_NAMES');
|
|
121
|
+
|
|
122
|
+
INSERT INTO "prefix_Metadata" ("key", "value", "note", "createdAt", "updatedAt")
|
|
123
|
+
SELECT 'SHIBBOLETH_DISPLAY_NAME_ATTRIBUTE_NAMES',
|
|
124
|
+
'displayName urn:oid:2.16.840.1.113730.3.1.241',
|
|
125
|
+
'Space-separated SAML attribute names accepted as the user display name during Shibboleth login.',
|
|
126
|
+
NOW(),
|
|
127
|
+
NOW()
|
|
128
|
+
WHERE NOT EXISTS (SELECT 1 FROM "prefix_Metadata" WHERE "key" = 'SHIBBOLETH_DISPLAY_NAME_ATTRIBUTE_NAMES');
|
|
129
|
+
|
|
130
|
+
INSERT INTO "prefix_Metadata" ("key", "value", "note", "createdAt", "updatedAt")
|
|
131
|
+
SELECT 'SHIBBOLETH_UNSTRUCTURED_NAME_ATTRIBUTE_NAMES',
|
|
132
|
+
'unstructuredName eduPersonPrincipalName urn:oid:1.3.6.1.4.1.5923.1.1.1.6 uid',
|
|
133
|
+
'Space-separated SAML attribute names accepted as the institutional identifier during Shibboleth login.',
|
|
134
|
+
NOW(),
|
|
135
|
+
NOW()
|
|
136
|
+
WHERE NOT EXISTS (SELECT 1 FROM "prefix_Metadata" WHERE "key" = 'SHIBBOLETH_UNSTRUCTURED_NAME_ATTRIBUTE_NAMES');
|
|
@@ -86,19 +86,14 @@ const JSON_COLUMNS_BY_TABLE = new Map<string, ReadonlySet<string>>([
|
|
|
86
86
|
['ShareTargetPayload', new Set(['attachments'])],
|
|
87
87
|
['CalendarConnection', new Set(['scopes'])],
|
|
88
88
|
['CalendarActivity', new Set(['details'])],
|
|
89
|
+
['ShibbolethUserIdentity', new Set(['rawAttributes'])],
|
|
90
|
+
['ShibbolethAuthenticationAttempt', new Set(['rawAttributes'])],
|
|
89
91
|
]);
|
|
90
92
|
|
|
91
93
|
/**
|
|
92
94
|
* Boolean columns stored as integers by SQLite and restored as booleans.
|
|
93
95
|
*/
|
|
94
|
-
const BOOLEAN_COLUMNS = new Set([
|
|
95
|
-
'isAdmin',
|
|
96
|
-
'isRevoked',
|
|
97
|
-
'isGlobal',
|
|
98
|
-
'isUserScoped',
|
|
99
|
-
'isSuccessful',
|
|
100
|
-
'isChatFocused',
|
|
101
|
-
]);
|
|
96
|
+
const BOOLEAN_COLUMNS = new Set(['isAdmin', 'isRevoked', 'isGlobal', 'isUserScoped', 'isSuccessful', 'isChatFocused']);
|
|
102
97
|
|
|
103
98
|
/**
|
|
104
99
|
* Tables whose primary key is provided as text rather than generated numerically.
|
|
@@ -122,6 +117,7 @@ const UNIQUE_INDEX_COLUMNS_BY_TABLE = new Map<string, ReadonlyArray<ReadonlyArra
|
|
|
122
117
|
['AgentExternals', [['type', 'hash']]],
|
|
123
118
|
['VectorStoreKnowledgeSourceHashes', [['source']]],
|
|
124
119
|
['User', [['username']]],
|
|
120
|
+
['ShibbolethUserIdentity', [['userId'], ['email'], ['nameId']]],
|
|
125
121
|
['UserChatJob', [['chatId', 'clientMessageId']]],
|
|
126
122
|
['LlmCache', [['hash']]],
|
|
127
123
|
['OpenAiAssistantCache', [['agentHash']]],
|
|
@@ -158,7 +154,9 @@ export function $provideLocalSqliteSupabase(): SupabaseClient {
|
|
|
158
154
|
return localSqliteSupabase;
|
|
159
155
|
}
|
|
160
156
|
|
|
161
|
-
localSqliteSupabase = new LocalSqliteSupabaseClient(
|
|
157
|
+
localSqliteSupabase = new LocalSqliteSupabaseClient(
|
|
158
|
+
$provideAgentsServerSqliteDatabase(),
|
|
159
|
+
) as unknown as SupabaseClient;
|
|
162
160
|
return localSqliteSupabase;
|
|
163
161
|
}
|
|
164
162
|
|
|
@@ -188,10 +186,7 @@ class LocalSqliteSupabaseClient {
|
|
|
188
186
|
* Supabase-shaped table entry point. Every operation starts a fresh query builder.
|
|
189
187
|
*/
|
|
190
188
|
class LocalSqliteTable {
|
|
191
|
-
public constructor(
|
|
192
|
-
private readonly database: AgentsServerSqliteDatabase,
|
|
193
|
-
private readonly tableName: string,
|
|
194
|
-
) {}
|
|
189
|
+
public constructor(private readonly database: AgentsServerSqliteDatabase, private readonly tableName: string) {}
|
|
195
190
|
|
|
196
191
|
/**
|
|
197
192
|
* Starts a select query.
|
|
@@ -248,10 +243,7 @@ class LocalSqliteQueryBuilder implements PromiseLike<LocalSqliteQueryResult> {
|
|
|
248
243
|
private signal: AbortSignal | null = null;
|
|
249
244
|
private isReturningSelection = false;
|
|
250
245
|
|
|
251
|
-
public constructor(
|
|
252
|
-
private readonly database: AgentsServerSqliteDatabase,
|
|
253
|
-
private readonly tableName: string,
|
|
254
|
-
) {}
|
|
246
|
+
public constructor(private readonly database: AgentsServerSqliteDatabase, private readonly tableName: string) {}
|
|
255
247
|
|
|
256
248
|
/**
|
|
257
249
|
* Configures selected columns or mutation return columns.
|
|
@@ -569,10 +561,16 @@ class LocalSqliteQueryBuilder implements PromiseLike<LocalSqliteQueryResult> {
|
|
|
569
561
|
|
|
570
562
|
if (rowids.length > 0 && updateColumns.length > 0) {
|
|
571
563
|
const assignments = updateColumns.map((column) => `${quoteIdentifier(column)} = ?`).join(', ');
|
|
572
|
-
const values = updateColumns.map((column) =>
|
|
564
|
+
const values = updateColumns.map((column) =>
|
|
565
|
+
serializeValue(this.tableName, column, this.mutationValues[column]),
|
|
566
|
+
);
|
|
573
567
|
const rowidPlaceholders = rowids.map(() => '?').join(', ');
|
|
574
568
|
this.database
|
|
575
|
-
.prepare(
|
|
569
|
+
.prepare(
|
|
570
|
+
`UPDATE ${quoteIdentifier(
|
|
571
|
+
this.tableName,
|
|
572
|
+
)} SET ${assignments} WHERE rowid IN (${rowidPlaceholders})`,
|
|
573
|
+
)
|
|
576
574
|
.run(...values, ...rowids);
|
|
577
575
|
}
|
|
578
576
|
|
|
@@ -591,7 +589,9 @@ class LocalSqliteQueryBuilder implements PromiseLike<LocalSqliteQueryResult> {
|
|
|
591
589
|
const rowids = this.selectMatchingRowids();
|
|
592
590
|
if (rowids.length > 0) {
|
|
593
591
|
const rowidPlaceholders = rowids.map(() => '?').join(', ');
|
|
594
|
-
this.database
|
|
592
|
+
this.database
|
|
593
|
+
.prepare(`DELETE FROM ${quoteIdentifier(this.tableName)} WHERE rowid IN (${rowidPlaceholders})`)
|
|
594
|
+
.run(...rowids);
|
|
595
595
|
}
|
|
596
596
|
|
|
597
597
|
return this.createMutationResponse([]);
|
|
@@ -608,7 +608,10 @@ class LocalSqliteQueryBuilder implements PromiseLike<LocalSqliteQueryResult> {
|
|
|
608
608
|
for (const rawRow of this.mutationRows) {
|
|
609
609
|
const row = withInsertDefaults(tableBaseName, rawRow);
|
|
610
610
|
ensureTable(this.database, this.tableName, [...Object.keys(row), ...conflictColumns]);
|
|
611
|
-
const existingRowid =
|
|
611
|
+
const existingRowid =
|
|
612
|
+
conflictColumns.length > 0
|
|
613
|
+
? findConflictRowid(this.database, this.tableName, row, conflictColumns)
|
|
614
|
+
: null;
|
|
612
615
|
|
|
613
616
|
if (existingRowid !== null) {
|
|
614
617
|
updateRowid(this.database, this.tableName, existingRowid, row);
|
|
@@ -634,7 +637,12 @@ class LocalSqliteQueryBuilder implements PromiseLike<LocalSqliteQueryResult> {
|
|
|
634
637
|
};
|
|
635
638
|
}
|
|
636
639
|
|
|
637
|
-
const data = selectRowsByRowids(
|
|
640
|
+
const data = selectRowsByRowids(
|
|
641
|
+
this.database,
|
|
642
|
+
this.tableName,
|
|
643
|
+
rowids,
|
|
644
|
+
parseSelectedColumns(this.selectedColumns),
|
|
645
|
+
);
|
|
638
646
|
return this.finalizeDataResponse(data, null);
|
|
639
647
|
}
|
|
640
648
|
|
|
@@ -824,7 +832,9 @@ function ensureTable(
|
|
|
824
832
|
}
|
|
825
833
|
|
|
826
834
|
database.exec(
|
|
827
|
-
`ALTER TABLE ${quoteIdentifier(tableName)} ADD COLUMN ${quoteIdentifier(column)} ${resolveSqliteColumnType(
|
|
835
|
+
`ALTER TABLE ${quoteIdentifier(tableName)} ADD COLUMN ${quoteIdentifier(column)} ${resolveSqliteColumnType(
|
|
836
|
+
column,
|
|
837
|
+
)}`,
|
|
828
838
|
);
|
|
829
839
|
existingColumns.add(column);
|
|
830
840
|
}
|
|
@@ -841,7 +851,11 @@ function ensureUniqueIndexes(database: AgentsServerSqliteDatabase, tableName: st
|
|
|
841
851
|
for (const columns of uniqueIndexes) {
|
|
842
852
|
const indexName = `idx_${sanitizeSqlIdentifier(tableName)}_${columns.join('_')}_unique`;
|
|
843
853
|
const columnSql = columns.map(quoteIdentifier).join(', ');
|
|
844
|
-
database.exec(
|
|
854
|
+
database.exec(
|
|
855
|
+
`CREATE UNIQUE INDEX IF NOT EXISTS ${quoteIdentifier(indexName)} ON ${quoteIdentifier(
|
|
856
|
+
tableName,
|
|
857
|
+
)} (${columnSql})`,
|
|
858
|
+
);
|
|
845
859
|
}
|
|
846
860
|
}
|
|
847
861
|
|
|
@@ -861,7 +875,9 @@ function insertRow(
|
|
|
861
875
|
|
|
862
876
|
const placeholders = columns.map(() => '?').join(', ');
|
|
863
877
|
const values = columns.map((column) => serializeValue(tableName, column, row[column]));
|
|
864
|
-
const sql = `INSERT INTO ${quoteIdentifier(tableName)} (${columns
|
|
878
|
+
const sql = `INSERT INTO ${quoteIdentifier(tableName)} (${columns
|
|
879
|
+
.map(quoteIdentifier)
|
|
880
|
+
.join(', ')}) VALUES (${placeholders})`;
|
|
865
881
|
|
|
866
882
|
return database.prepare(sql).run(...values);
|
|
867
883
|
}
|
|
@@ -900,7 +916,9 @@ function findConflictRowid(
|
|
|
900
916
|
|
|
901
917
|
const conditions = conflictColumns.map((column) => `${quoteIdentifier(column)} = ?`).join(' AND ');
|
|
902
918
|
const values = conflictColumns.map((column) => serializeValue(tableName, column, row[column]));
|
|
903
|
-
const result = database
|
|
919
|
+
const result = database
|
|
920
|
+
.prepare(`SELECT rowid FROM ${quoteIdentifier(tableName)} WHERE ${conditions} LIMIT 1`)
|
|
921
|
+
.get(...values);
|
|
904
922
|
|
|
905
923
|
return result ? (result.rowid as number | bigint) : null;
|
|
906
924
|
}
|
|
@@ -922,7 +940,9 @@ function selectRowsByRowids(
|
|
|
922
940
|
const placeholders = rowids.map(() => '?').join(', ');
|
|
923
941
|
const rows = database
|
|
924
942
|
.prepare(
|
|
925
|
-
`SELECT ${createSelectExpression(selectedColumns)} FROM ${quoteIdentifier(
|
|
943
|
+
`SELECT ${createSelectExpression(selectedColumns)} FROM ${quoteIdentifier(
|
|
944
|
+
tableName,
|
|
945
|
+
)} WHERE rowid IN (${placeholders})`,
|
|
926
946
|
)
|
|
927
947
|
.all(...rowids);
|
|
928
948
|
|
|
@@ -941,17 +961,25 @@ function createFilterCondition(
|
|
|
941
961
|
|
|
942
962
|
switch (filter.operator) {
|
|
943
963
|
case 'eq':
|
|
944
|
-
return value === null
|
|
964
|
+
return value === null
|
|
965
|
+
? { sql: `${column} IS NULL`, values: [] }
|
|
966
|
+
: { sql: `${column} = ?`, values: [value] };
|
|
945
967
|
case 'neq':
|
|
946
968
|
return value === null
|
|
947
969
|
? { sql: `${column} IS NOT NULL`, values: [] }
|
|
948
970
|
: { sql: `${column} <> ?`, values: [value] };
|
|
949
971
|
case 'is':
|
|
950
|
-
return filter.value === null
|
|
972
|
+
return filter.value === null
|
|
973
|
+
? { sql: `${column} IS NULL`, values: [] }
|
|
974
|
+
: { sql: `${column} IS ?`, values: [value] };
|
|
951
975
|
case 'not-is':
|
|
952
|
-
return filter.value === null
|
|
976
|
+
return filter.value === null
|
|
977
|
+
? { sql: `${column} IS NOT NULL`, values: [] }
|
|
978
|
+
: { sql: `${column} IS NOT ?`, values: [value] };
|
|
953
979
|
case 'in': {
|
|
954
|
-
const values = Array.isArray(filter.value)
|
|
980
|
+
const values = Array.isArray(filter.value)
|
|
981
|
+
? filter.value.map((item) => serializeValue(tableName, filter.column, item))
|
|
982
|
+
: [];
|
|
955
983
|
if (values.length === 0) {
|
|
956
984
|
return { sql: '0 = 1', values: [] };
|
|
957
985
|
}
|
|
@@ -1190,6 +1218,30 @@ function withInsertDefaults(tableBaseName: string, row: Record<string, unknown>)
|
|
|
1190
1218
|
case 'User':
|
|
1191
1219
|
result.isAdmin ??= false;
|
|
1192
1220
|
result.profileImageUrl ??= null;
|
|
1221
|
+
result.email ??= null;
|
|
1222
|
+
result.displayName ??= null;
|
|
1223
|
+
result.authenticationProvider ??= 'LOCAL';
|
|
1224
|
+
break;
|
|
1225
|
+
case 'ShibbolethUserIdentity':
|
|
1226
|
+
result.displayName ??= null;
|
|
1227
|
+
result.nameId ??= null;
|
|
1228
|
+
result.nameIdFormat ??= null;
|
|
1229
|
+
result.unstructuredName ??= null;
|
|
1230
|
+
result.eduPersonPrincipalName ??= null;
|
|
1231
|
+
result.rawAttributes ??= null;
|
|
1232
|
+
result.lastLoggedInAt ??= null;
|
|
1233
|
+
result.loginCount ??= 0;
|
|
1234
|
+
break;
|
|
1235
|
+
case 'ShibbolethAuthenticationAttempt':
|
|
1236
|
+
result.userId ??= null;
|
|
1237
|
+
result.email ??= null;
|
|
1238
|
+
result.displayName ??= null;
|
|
1239
|
+
result.nameId ??= null;
|
|
1240
|
+
result.relayState ??= null;
|
|
1241
|
+
result.ip ??= null;
|
|
1242
|
+
result.userAgent ??= null;
|
|
1243
|
+
result.errorMessage ??= null;
|
|
1244
|
+
result.rawAttributes ??= null;
|
|
1193
1245
|
break;
|
|
1194
1246
|
case 'UserChat':
|
|
1195
1247
|
result.messages ??= [];
|
|
@@ -1342,10 +1394,7 @@ function resolveUniqueIndexColumns(tableBaseName: string): Array<string> {
|
|
|
1342
1394
|
/**
|
|
1343
1395
|
* Resolves upsert conflict columns.
|
|
1344
1396
|
*/
|
|
1345
|
-
function resolveUpsertConflictColumns(
|
|
1346
|
-
tableBaseName: string,
|
|
1347
|
-
options: LocalSqliteUpsertOptions,
|
|
1348
|
-
): ReadonlyArray<string> {
|
|
1397
|
+
function resolveUpsertConflictColumns(tableBaseName: string, options: LocalSqliteUpsertOptions): ReadonlyArray<string> {
|
|
1349
1398
|
if (options.onConflict) {
|
|
1350
1399
|
return options.onConflict
|
|
1351
1400
|
.split(',')
|
|
@@ -1367,7 +1416,10 @@ function normalizeSqliteError(error: unknown): LocalSqliteError {
|
|
|
1367
1416
|
: undefined;
|
|
1368
1417
|
|
|
1369
1418
|
return {
|
|
1370
|
-
code:
|
|
1419
|
+
code:
|
|
1420
|
+
sqliteCode === 'SQLITE_CONSTRAINT_UNIQUE' || sqliteCode === 'SQLITE_CONSTRAINT_PRIMARYKEY'
|
|
1421
|
+
? '23505'
|
|
1422
|
+
: sqliteCode,
|
|
1371
1423
|
message,
|
|
1372
1424
|
};
|
|
1373
1425
|
}
|
|
@@ -128,6 +128,7 @@ export const SERVER_TRANSLATION_KEYS = [
|
|
|
128
128
|
'header.myAccount',
|
|
129
129
|
'header.superAdmin',
|
|
130
130
|
'header.administration',
|
|
131
|
+
'header.loginMethods',
|
|
131
132
|
'header.monitoringAndUsage',
|
|
132
133
|
'header.integrationsAndKeys',
|
|
133
134
|
'header.developerDebug',
|
|
@@ -168,6 +169,7 @@ export const SERVER_TRANSLATION_KEYS = [
|
|
|
168
169
|
'header.imagesGallery',
|
|
169
170
|
'header.files',
|
|
170
171
|
'header.users',
|
|
172
|
+
'header.shibboleth',
|
|
171
173
|
'header.versionInfo',
|
|
172
174
|
'header.experiments',
|
|
173
175
|
'header.story',
|
|
@@ -198,8 +200,8 @@ export const SERVER_TRANSLATION_KEYS = [
|
|
|
198
200
|
'login.passwordPlaceholder',
|
|
199
201
|
'login.loggingIn',
|
|
200
202
|
'login.loginAction',
|
|
201
|
-
'login.
|
|
202
|
-
'login.
|
|
203
|
+
'login.shibbolethLoginAction',
|
|
204
|
+
'login.shibbolethNotConfigured',
|
|
203
205
|
'login.forgottenPassword',
|
|
204
206
|
'login.registerNewUser',
|
|
205
207
|
'login.errorOccurred',
|
|
@@ -122,6 +122,7 @@ header.menuLabel: Nabídka
|
|
|
122
122
|
header.myAccount: Můj účet
|
|
123
123
|
header.superAdmin: Super administrace
|
|
124
124
|
header.administration: Administrace
|
|
125
|
+
header.loginMethods: Metody přihlášení
|
|
125
126
|
header.monitoringAndUsage: Monitoring a využití
|
|
126
127
|
header.integrationsAndKeys: Integrace a klíče
|
|
127
128
|
header.developerDebug: Vývoj a ladění
|
|
@@ -162,6 +163,7 @@ header.errorSimulation: Simulace chyb
|
|
|
162
163
|
header.imagesGallery: Galerie obrázků
|
|
163
164
|
header.files: Soubory
|
|
164
165
|
header.users: Uživatelé
|
|
166
|
+
header.shibboleth: Shibboleth
|
|
165
167
|
header.versionInfo: Informace o verzi
|
|
166
168
|
header.experiments: Experimenty
|
|
167
169
|
header.story: Příběh
|
|
@@ -192,8 +194,8 @@ login.passwordLabel: Heslo
|
|
|
192
194
|
login.passwordPlaceholder: Zadejte heslo
|
|
193
195
|
login.loggingIn: Přihlašuji…
|
|
194
196
|
login.loginAction: Přihlásit se
|
|
195
|
-
login.
|
|
196
|
-
login.
|
|
197
|
+
login.shibbolethLoginAction: Pokračovat přes Shibboleth
|
|
198
|
+
login.shibbolethNotConfigured: Přihlášení přes Shibboleth je aktivní, ale vyžaduje nastavení správcem.
|
|
197
199
|
login.forgottenPassword: Zapomněli jste heslo?
|
|
198
200
|
login.registerNewUser: Zaregistrovat nového uživatele
|
|
199
201
|
login.errorOccurred: Došlo k chybě
|