@promptbook/cli 0.112.0-101 → 0.112.0-103

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.
Files changed (91) hide show
  1. package/apps/agents-server/package.json +1 -1
  2. package/apps/agents-server/scripts/prerender-homepage.js +76 -1
  3. package/apps/agents-server/src/app/actions.ts +0 -6
  4. package/apps/agents-server/src/app/admin/about/page.tsx +1 -1
  5. package/apps/agents-server/src/app/admin/image-generator-test/ImageAttachmentsEditor.tsx +11 -6
  6. package/apps/agents-server/src/app/admin/login-methods/shibboleth/page.tsx +365 -0
  7. package/apps/agents-server/src/app/admin/metadata/MetadataClient.tsx +13 -15
  8. package/apps/agents-server/src/app/admin/servers/ServersRegistryTable.tsx +3 -3
  9. package/apps/agents-server/src/app/admin/servers/useCreateServerWizard.ts +13 -14
  10. package/apps/agents-server/src/app/admin/update/UpdateClient.tsx +12 -3
  11. package/apps/agents-server/src/app/admin/usage/UsageClientTimelineChart.tsx +1 -1
  12. package/apps/agents-server/src/app/admin/users/[userId]/UserDetailClient.tsx +21 -14
  13. package/apps/agents-server/src/app/agents/[agentName]/chat/AgentChatPageLayout.tsx +2 -2
  14. package/apps/agents-server/src/app/agents/[agentName]/chat/AgentChatSidebarDefault.tsx +11 -7
  15. package/apps/agents-server/src/app/api/admin/cli-access/route.ts +27 -123
  16. package/apps/agents-server/src/app/api/admin/code-runners/authentication/route.ts +33 -125
  17. package/apps/agents-server/src/app/api/auth/login/route.ts +0 -10
  18. package/apps/agents-server/src/app/api/auth/shibboleth/acs/route.ts +77 -57
  19. package/apps/agents-server/src/app/api/auth/shibboleth/login/route.ts +57 -33
  20. package/apps/agents-server/src/app/api/auth/shibboleth/metadata/route.ts +4 -29
  21. package/apps/agents-server/src/app/api/auth/shibboleth/status/route.ts +17 -0
  22. package/apps/agents-server/src/app/api/upload/route.ts +148 -209
  23. package/apps/agents-server/src/app/api/users/[username]/route.ts +1 -1
  24. package/apps/agents-server/src/app/api/users/route.ts +5 -5
  25. package/apps/agents-server/src/app/dashboard/page.tsx +1 -1
  26. package/apps/agents-server/src/app/docs/[docId]/page.tsx +1 -1
  27. package/apps/agents-server/src/app/docs/page.tsx +1 -1
  28. package/apps/agents-server/src/app/globals.css +100 -0
  29. package/apps/agents-server/src/app/layout.tsx +7 -0
  30. package/apps/agents-server/src/app/recycle-bin/page.tsx +1 -1
  31. package/apps/agents-server/src/app/system/settings/KeybindingsSettingsClient.tsx +13 -7
  32. package/apps/agents-server/src/components/AdminTerminal/useAdminTerminalSession.ts +29 -1
  33. package/apps/agents-server/src/components/AgentProfile/AgentProfile.tsx +3 -3
  34. package/apps/agents-server/src/components/AgentProfile/AgentProfileImage.tsx +8 -2
  35. package/apps/agents-server/src/components/DocsToolbar/DocsToolbar.tsx +4 -4
  36. package/apps/agents-server/src/components/DocumentationContent/DocumentationContent.tsx +9 -9
  37. package/apps/agents-server/src/components/Footer/Footer.tsx +7 -7
  38. package/apps/agents-server/src/components/Header/Header.tsx +24 -4
  39. package/apps/agents-server/src/components/Header/HeaderTypes.ts +6 -0
  40. package/apps/agents-server/src/components/Header/buildHeaderSystemMenuItems.ts +51 -1
  41. package/apps/agents-server/src/components/Homepage/Card.tsx +1 -1
  42. package/apps/agents-server/src/components/Homepage/Section.tsx +3 -1
  43. package/apps/agents-server/src/components/LayoutWrapper/LayoutWrapper.tsx +12 -1
  44. package/apps/agents-server/src/components/LoginForm/LoginForm.tsx +100 -149
  45. package/apps/agents-server/src/components/Skeleton/ConsolePageLoadingSkeleton.tsx +1 -1
  46. package/apps/agents-server/src/components/Skeleton/DocumentationRouteLoadingSkeleton.tsx +1 -1
  47. package/apps/agents-server/src/components/Skeleton/HomepageLoadingSkeleton.tsx +1 -1
  48. package/apps/agents-server/src/components/UsersList/UsersList.tsx +20 -4
  49. package/apps/agents-server/src/components/UsersList/useUsersAdmin.ts +3 -0
  50. package/apps/agents-server/src/constants/shibbolethAuth.ts +139 -0
  51. package/apps/agents-server/src/database/metadataDefaults.ts +54 -80
  52. package/apps/agents-server/src/database/migrate.ts +30 -1
  53. package/apps/agents-server/src/database/migrations/2026-06-0100-shibboleth-auth.sql +136 -0
  54. package/apps/agents-server/src/database/sqlite/$provideLocalSqliteSupabase.ts +88 -36
  55. package/apps/agents-server/src/languages/ServerTranslationKeys.ts +4 -2
  56. package/apps/agents-server/src/languages/translations/czech.yaml +4 -2
  57. package/apps/agents-server/src/languages/translations/english.yaml +5 -3
  58. package/apps/agents-server/src/tools/$provideCdnForServer.ts +54 -11
  59. package/apps/agents-server/src/utils/cdn/classes/DigitalOceanSpaces.ts +18 -2
  60. package/apps/agents-server/src/utils/cdn/classes/TrackedFilesStorage.ts +6 -5
  61. package/apps/agents-server/src/utils/cdn/interfaces/IFilesStorage.ts +5 -0
  62. package/apps/agents-server/src/utils/chatExport/renderHtmlToPdfOnServer.ts +11 -0
  63. package/apps/agents-server/src/utils/createAdminTerminalRouteHandlers.ts +264 -0
  64. package/apps/agents-server/src/utils/shareTargetPayloads.ts +19 -66
  65. package/apps/agents-server/src/utils/shibbolethAuthentication.ts +729 -621
  66. package/apps/agents-server/src/utils/upload/createBookEditorUploadHandler.ts +19 -28
  67. package/apps/agents-server/src/utils/upload/uploadFileToServer.ts +113 -0
  68. package/esm/index.es.js +194 -35
  69. package/esm/index.es.js.map +1 -1
  70. package/esm/scripts/run-codex-prompts/common/waitForPause.d.ts +12 -0
  71. package/esm/scripts/run-codex-prompts/main/runPromptRound.d.ts +2 -1
  72. package/esm/scripts/run-codex-prompts/ui/buildCoderRunUiFrame.d.ts +1 -0
  73. package/esm/scripts/run-codex-prompts/ui/buildRunUiFrameShared.d.ts +1 -1
  74. package/esm/src/book-components/Chat/MarkdownContent/MarkdownContent.d.ts +1 -0
  75. package/esm/src/version.d.ts +1 -1
  76. package/package.json +2 -2
  77. package/src/book-components/Chat/MarkdownContent/MarkdownContent.tsx +63 -4
  78. package/src/other/templates/getTemplatesPipelineCollection.ts +730 -739
  79. package/src/version.ts +2 -2
  80. package/src/versions.txt +2 -0
  81. package/umd/index.umd.js +194 -35
  82. package/umd/index.umd.js.map +1 -1
  83. package/umd/scripts/run-codex-prompts/common/waitForPause.d.ts +12 -0
  84. package/umd/scripts/run-codex-prompts/main/runPromptRound.d.ts +2 -1
  85. package/umd/scripts/run-codex-prompts/ui/buildCoderRunUiFrame.d.ts +1 -0
  86. package/umd/scripts/run-codex-prompts/ui/buildRunUiFrameShared.d.ts +1 -1
  87. package/umd/src/book-components/Chat/MarkdownContent/MarkdownContent.d.ts +1 -0
  88. package/umd/src/version.d.ts +1 -1
  89. package/apps/agents-server/src/app/api/auth/methods/route.ts +0 -44
  90. package/apps/agents-server/src/constants/authenticationMethods.ts +0 -74
  91. package/apps/agents-server/src/constants/shibbolethAuthentication.ts +0 -107
@@ -1,92 +1,112 @@
1
- import { NextRequest, NextResponse } from 'next/server';
2
- import { setSession } from '../../../../../utils/session';
1
+ import { revalidatePath } from 'next/cache';
2
+ import { NextResponse } from 'next/server';
3
3
  import {
4
- createShibbolethProfileLogDetails,
5
4
  createShibbolethSamlClient,
6
- loadShibbolethConfiguration,
7
- logShibbolethAuthenticationEvent,
8
- resolveSafeShibbolethRelayState,
9
- resolveShibbolethUser,
10
- ShibbolethConfigurationError,
5
+ findOrCreateShibbolethUser,
6
+ getShibbolethRequestDetails,
7
+ recordShibbolethAuthenticationAttempt,
8
+ resolveShibbolethAuthenticationConfiguration,
9
+ sanitizeShibbolethRelayState,
11
10
  } from '../../../../../utils/shibbolethAuthentication';
12
-
13
- /**
14
- * Forces this route to run in Node.js because node-saml depends on Node crypto/zlib APIs.
15
- */
16
- export const runtime = 'nodejs';
11
+ import { setSession } from '../../../../../utils/session';
17
12
 
18
13
  /**
19
14
  * Handles post.
20
15
  */
21
- export async function POST(request: NextRequest) {
22
- const configuration = await loadShibbolethConfiguration(request);
23
-
24
- if (!configuration.isEnabled) {
25
- logShibbolethAuthenticationEvent('acs_rejected_disabled');
26
- return NextResponse.json({ error: 'Shibboleth authentication is not enabled.' }, { status: 404 });
27
- }
28
-
29
- if (!configuration.isConfigured) {
30
- const error = new ShibbolethConfigurationError(configuration.missingConfiguration);
31
- logShibbolethAuthenticationEvent('acs_rejected_incomplete_configuration', {
32
- missingConfiguration: configuration.missingConfiguration,
33
- });
34
- return NextResponse.json({ error: error.message }, { status: 503 });
35
- }
16
+ export async function POST(request: Request) {
17
+ const requestDetails = getShibbolethRequestDetails(request);
18
+ let relayState = '/';
36
19
 
37
20
  try {
38
21
  const formData = await request.formData();
39
22
  const samlResponse = formData.get('SAMLResponse');
40
- const relayState = resolveSafeShibbolethRelayState(
41
- typeof formData.get('RelayState') === 'string' ? String(formData.get('RelayState')) : null,
42
- );
23
+ relayState = sanitizeShibbolethRelayState(formData.get('RelayState')?.toString());
43
24
 
44
- if (typeof samlResponse !== 'string' || samlResponse.trim() === '') {
45
- logShibbolethAuthenticationEvent('acs_rejected_missing_saml_response');
25
+ if (typeof samlResponse !== 'string' || !samlResponse) {
26
+ await recordShibbolethAuthenticationAttempt({
27
+ stage: 'ASSERTION_CONSUMER_SERVICE',
28
+ status: 'FAILED',
29
+ requestDetails,
30
+ relayState,
31
+ errorMessage: 'Missing SAMLResponse.',
32
+ });
46
33
  return NextResponse.json({ error: 'Missing SAMLResponse.' }, { status: 400 });
47
34
  }
48
35
 
49
- logShibbolethAuthenticationEvent('acs_response_received', {
50
- relayState,
51
- responseLength: samlResponse.length,
36
+ const configuration = await resolveShibbolethAuthenticationConfiguration({
37
+ requestUrl: request.url,
38
+ isIdentityProviderMetadataValidationEnabled: true,
52
39
  });
53
40
 
41
+ if (!configuration.isActive) {
42
+ await recordShibbolethAuthenticationAttempt({
43
+ stage: 'ASSERTION_CONSUMER_SERVICE',
44
+ status: 'REJECTED',
45
+ requestDetails,
46
+ relayState,
47
+ errorMessage: 'Shibboleth authentication is not active.',
48
+ });
49
+ return NextResponse.json({ error: 'Shibboleth authentication is not active.' }, { status: 404 });
50
+ }
51
+
52
+ if (!configuration.isConfigured) {
53
+ const errorMessage = configuration.errors.join(' ');
54
+ await recordShibbolethAuthenticationAttempt({
55
+ stage: 'ASSERTION_CONSUMER_SERVICE',
56
+ status: 'FAILED',
57
+ requestDetails,
58
+ relayState,
59
+ errorMessage,
60
+ });
61
+ return NextResponse.json({ error: errorMessage }, { status: 503 });
62
+ }
63
+
54
64
  const saml = createShibbolethSamlClient(configuration);
55
- const { profile } = await saml.validatePostResponseAsync({
56
- SAMLResponse: samlResponse,
57
- RelayState: relayState,
58
- });
65
+ const { profile } = await saml.validatePostResponseAsync({ SAMLResponse: samlResponse });
59
66
 
60
67
  if (!profile) {
61
- logShibbolethAuthenticationEvent('acs_rejected_empty_profile');
62
- return NextResponse.json({ error: 'Shibboleth did not return a user profile.' }, { status: 401 });
68
+ await recordShibbolethAuthenticationAttempt({
69
+ stage: 'ASSERTION_CONSUMER_SERVICE',
70
+ status: 'FAILED',
71
+ requestDetails,
72
+ relayState,
73
+ errorMessage: 'Shibboleth response did not include a user profile.',
74
+ });
75
+ return NextResponse.json({ error: 'Shibboleth response did not include a user profile.' }, { status: 401 });
63
76
  }
64
77
 
65
- logShibbolethAuthenticationEvent(
66
- 'acs_profile_validated',
67
- createShibbolethProfileLogDetails(profile, configuration.usernameAttribute),
68
- );
69
-
70
- const user = await resolveShibbolethUser(profile, configuration);
78
+ const linkedUser = await findOrCreateShibbolethUser(profile);
71
79
  await setSession({
72
- username: user.username,
73
- isAdmin: user.isAdmin,
80
+ username: linkedUser.user.username,
81
+ isAdmin: linkedUser.user.isAdmin,
74
82
  isGlobalAdmin: false,
75
83
  });
84
+ revalidatePath('/', 'layout');
76
85
 
77
- logShibbolethAuthenticationEvent('acs_session_created', {
78
- username: user.username,
79
- isAdmin: user.isAdmin,
80
- isNewUser: user.isNewUser,
86
+ await recordShibbolethAuthenticationAttempt({
87
+ stage: 'ASSERTION_CONSUMER_SERVICE',
88
+ status: 'SUCCESS',
89
+ requestDetails,
81
90
  relayState,
91
+ userId: linkedUser.user.id,
92
+ email: linkedUser.profileAttributes.email,
93
+ displayName: linkedUser.profileAttributes.displayName,
94
+ nameId: linkedUser.profileAttributes.nameId,
95
+ rawAttributes: linkedUser.profileAttributes.rawAttributes,
82
96
  });
83
97
 
84
98
  return NextResponse.redirect(new URL(relayState, request.url), 303);
85
99
  } catch (error) {
86
- logShibbolethAuthenticationEvent('acs_failed', {
87
- error: error instanceof Error ? error.message : String(error),
100
+ const errorMessage = error instanceof Error ? error.message : 'Failed to finish Shibboleth authentication.';
101
+ await recordShibbolethAuthenticationAttempt({
102
+ stage: 'ASSERTION_CONSUMER_SERVICE',
103
+ status: 'FAILED',
104
+ requestDetails,
105
+ relayState,
106
+ errorMessage,
88
107
  });
89
108
 
90
- return NextResponse.json({ error: 'Shibboleth authentication failed.' }, { status: 401 });
109
+ console.error('Shibboleth assertion consumer service error:', error);
110
+ return NextResponse.json({ error: errorMessage }, { status: 401 });
91
111
  }
92
112
  }
@@ -1,46 +1,70 @@
1
- import { NextRequest, NextResponse } from 'next/server';
1
+ import { NextResponse } from 'next/server';
2
2
  import {
3
3
  createShibbolethSamlClient,
4
- loadShibbolethConfiguration,
5
- logShibbolethAuthenticationEvent,
6
- resolveSafeShibbolethRelayState,
7
- ShibbolethConfigurationError,
4
+ getShibbolethRequestDetails,
5
+ recordShibbolethAuthenticationAttempt,
6
+ resolveShibbolethAuthenticationConfiguration,
7
+ sanitizeShibbolethRelayState,
8
8
  } from '../../../../../utils/shibbolethAuthentication';
9
9
 
10
- /**
11
- * Forces this route to run in Node.js because node-saml depends on Node crypto/zlib APIs.
12
- */
13
- export const runtime = 'nodejs';
14
-
15
10
  /**
16
11
  * Handles get.
17
12
  */
18
- export async function GET(request: NextRequest) {
19
- const configuration = await loadShibbolethConfiguration(request);
13
+ export async function GET(request: Request) {
14
+ const requestDetails = getShibbolethRequestDetails(request);
15
+ const relayState = sanitizeShibbolethRelayState(new URL(request.url).searchParams.get('returnTo'));
20
16
 
21
- if (!configuration.isEnabled) {
22
- logShibbolethAuthenticationEvent('login_rejected_disabled');
23
- return NextResponse.json({ error: 'Shibboleth authentication is not enabled.' }, { status: 404 });
24
- }
25
-
26
- if (!configuration.isConfigured) {
27
- const error = new ShibbolethConfigurationError(configuration.missingConfiguration);
28
- logShibbolethAuthenticationEvent('login_rejected_incomplete_configuration', {
29
- missingConfiguration: configuration.missingConfiguration,
17
+ try {
18
+ const configuration = await resolveShibbolethAuthenticationConfiguration({
19
+ requestUrl: request.url,
20
+ isIdentityProviderMetadataValidationEnabled: true,
30
21
  });
31
- return NextResponse.json({ error: error.message }, { status: 503 });
32
- }
33
22
 
34
- const relayState = resolveSafeShibbolethRelayState(request.nextUrl.searchParams.get('redirectTo'));
35
- const saml = createShibbolethSamlClient(configuration);
36
- const redirectUrl = await saml.getAuthorizeUrlAsync(relayState, undefined, {});
23
+ if (!configuration.isActive) {
24
+ await recordShibbolethAuthenticationAttempt({
25
+ stage: 'LOGIN_REQUEST',
26
+ status: 'REJECTED',
27
+ requestDetails,
28
+ relayState,
29
+ errorMessage: 'Shibboleth authentication is not active.',
30
+ });
31
+ return NextResponse.json({ error: 'Shibboleth authentication is not active.' }, { status: 404 });
32
+ }
37
33
 
38
- logShibbolethAuthenticationEvent('login_redirect_created', {
39
- issuer: configuration.issuer,
40
- callbackUrl: configuration.callbackUrl,
41
- entryPoint: configuration.entryPoint,
42
- relayState,
43
- });
34
+ if (!configuration.isConfigured) {
35
+ const errorMessage = configuration.errors.join(' ');
36
+ await recordShibbolethAuthenticationAttempt({
37
+ stage: 'LOGIN_REQUEST',
38
+ status: 'FAILED',
39
+ requestDetails,
40
+ relayState,
41
+ errorMessage,
42
+ });
43
+ return NextResponse.json({ error: errorMessage }, { status: 503 });
44
+ }
44
45
 
45
- return NextResponse.redirect(redirectUrl);
46
+ const saml = createShibbolethSamlClient(configuration);
47
+ const authorizeUrl = await saml.getAuthorizeUrlAsync(relayState, undefined, {});
48
+
49
+ await recordShibbolethAuthenticationAttempt({
50
+ stage: 'LOGIN_REQUEST',
51
+ status: 'REDIRECTED',
52
+ requestDetails,
53
+ relayState,
54
+ });
55
+
56
+ return NextResponse.redirect(authorizeUrl);
57
+ } catch (error) {
58
+ const errorMessage = error instanceof Error ? error.message : 'Failed to start Shibboleth authentication.';
59
+ await recordShibbolethAuthenticationAttempt({
60
+ stage: 'LOGIN_REQUEST',
61
+ status: 'FAILED',
62
+ requestDetails,
63
+ relayState,
64
+ errorMessage,
65
+ });
66
+
67
+ console.error('Shibboleth login start error:', error);
68
+ return NextResponse.json({ error: errorMessage }, { status: 500 });
69
+ }
46
70
  }
@@ -1,40 +1,15 @@
1
- import { NextRequest, NextResponse } from 'next/server';
2
- import {
3
- createShibbolethServiceProviderMetadata,
4
- loadShibbolethConfiguration,
5
- logShibbolethAuthenticationEvent,
6
- } from '../../../../../utils/shibbolethAuthentication';
7
-
8
- /**
9
- * Forces this route to run in Node.js because node-saml metadata generation depends on Node APIs.
10
- */
11
- export const runtime = 'nodejs';
1
+ import { NextResponse } from 'next/server';
2
+ import { createShibbolethServiceProviderMetadataXml } from '../../../../../utils/shibbolethAuthentication';
12
3
 
13
4
  /**
14
5
  * Handles get.
15
6
  */
16
- export async function GET(request: NextRequest) {
17
- const configuration = await loadShibbolethConfiguration(request);
18
-
19
- if (!configuration.isEnabled || !configuration.issuer || !configuration.callbackUrl) {
20
- logShibbolethAuthenticationEvent('metadata_rejected_disabled');
21
- return NextResponse.json({ error: 'Shibboleth authentication is not enabled.' }, { status: 404 });
22
- }
23
-
24
- const metadataXml = createShibbolethServiceProviderMetadata({
25
- issuer: configuration.issuer,
26
- callbackUrl: configuration.callbackUrl,
27
- });
28
-
29
- logShibbolethAuthenticationEvent('metadata_served', {
30
- issuer: configuration.issuer,
31
- callbackUrl: configuration.callbackUrl,
32
- });
7
+ export async function GET(request: Request) {
8
+ const metadataXml = await createShibbolethServiceProviderMetadataXml(request.url);
33
9
 
34
10
  return new NextResponse(metadataXml, {
35
11
  headers: {
36
12
  'Content-Type': 'application/samlmetadata+xml; charset=utf-8',
37
- 'Cache-Control': 'no-store',
38
13
  },
39
14
  });
40
15
  }
@@ -0,0 +1,17 @@
1
+ import { NextResponse } from 'next/server';
2
+ import { resolveShibbolethAuthenticationConfiguration } from '../../../../../utils/shibbolethAuthentication';
3
+
4
+ /**
5
+ * Handles get.
6
+ */
7
+ export async function GET(request: Request) {
8
+ const configuration = await resolveShibbolethAuthenticationConfiguration({
9
+ requestUrl: request.url,
10
+ isIdentityProviderMetadataValidationEnabled: false,
11
+ });
12
+
13
+ return NextResponse.json({
14
+ isActive: configuration.isActive,
15
+ isConfigured: configuration.isConfigured,
16
+ });
17
+ }