@anthusai/papyrus 1.0.0-next.62 → 1.0.0-next.64
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/amplify/auth/prospectus-google-client.js +66 -0
- package/amplify/auth/prospectus-google-client.ts +71 -0
- package/amplify/auth/resource.js +4 -1
- package/amplify/auth/resource.ts +5 -1
- package/amplify/data/resource.js +4 -0
- package/amplify/data/resource.ts +4 -0
- package/amplify/data/schema.js +4 -0
- package/amplify/data/schema.ts +4 -0
- package/amplify/site-backend.js +8 -1
- package/amplify/site-backend.ts +9 -1
- package/app/api/auth/prospectus/callback/route.ts +9 -0
- package/app/api/auth/prospectus/selection/route.ts +9 -0
- package/app/api/auth/prospectus/session/route.ts +9 -0
- package/app/api/auth/prospectus/sign-in/route.ts +9 -0
- package/app/api/auth/prospectus/sign-out/route.ts +9 -0
- package/components/news-desk-taxonomy-client.ts +37 -1
- package/components/newsroom-board-view.tsx +7 -8
- package/components/priming-proof-page.tsx +7 -5
- package/components/topic-steering-workspace.tsx +4 -0
- package/infra/amplify-app-shell.js +20 -2
- package/infra/amplify-app-shell.ts +22 -2
- package/infra/site-config.js +1 -1
- package/infra/site-config.ts +1 -1
- package/lib/category-repository.ts +1 -0
- package/lib/content-item-lifecycle.ts +55 -0
- package/lib/newsroom-board.ts +60 -21
- package/lib/newsroom-nav.ts +2 -1
- package/lib/newsroom-organizer-nav.ts +5 -2
- package/lib/priming-proof-report.ts +1 -0
- package/lib/prospectus-publication-access.ts +53 -0
- package/lib/prospectus-session.ts +196 -0
- package/lib/prospectus-sign-in-routes.ts +284 -0
- package/lib/site-brand.ts +19 -0
- package/package.json +11 -1
- package/routes.manifest.json +56 -1
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
import { NextResponse, type NextRequest } from "next/server";
|
|
2
|
+
import {
|
|
3
|
+
CYCLOTRON_LAB_PRODUCT,
|
|
4
|
+
ProspectusAccountsError,
|
|
5
|
+
authorizeSignedInPersonForAccount,
|
|
6
|
+
beginProspectusGoogleSignIn,
|
|
7
|
+
completeProspectusGoogleSignIn,
|
|
8
|
+
type CompleteProspectusGoogleSignInInput,
|
|
9
|
+
} from "./prospectus-site-identity";
|
|
10
|
+
import {
|
|
11
|
+
PROSPECTUS_PENDING_SIGN_IN_COOKIE,
|
|
12
|
+
PROSPECTUS_SESSION_COOKIE,
|
|
13
|
+
openProspectusCookie,
|
|
14
|
+
resolveProspectusSignInRuntime,
|
|
15
|
+
sameSiteReturnPath,
|
|
16
|
+
sealProspectusCookie,
|
|
17
|
+
sealedCookieAttributes,
|
|
18
|
+
type PendingProspectusSignInCookie,
|
|
19
|
+
type ProspectusSignInRuntime,
|
|
20
|
+
type ProspectusSignedInSession,
|
|
21
|
+
} from "./prospectus-session";
|
|
22
|
+
import {
|
|
23
|
+
prospectusSiteProduct,
|
|
24
|
+
publicationCapabilitiesForProspectusRole,
|
|
25
|
+
publishingAccountsForSite,
|
|
26
|
+
type PublicationCapability,
|
|
27
|
+
} from "./prospectus-publication-access";
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* The site's sign-in routes for Prospectus accounts: start (challenge, then the
|
|
31
|
+
* Google-only Cognito redirect), callback (verify, resolve, seal the session),
|
|
32
|
+
* session (who is signed in and which accounts they belong to) and sign-out.
|
|
33
|
+
* Every route answers 503 until the site is registered and configured, so an
|
|
34
|
+
* unregistered deployment never half-signs anyone in.
|
|
35
|
+
*/
|
|
36
|
+
export interface ProspectusSignInRouteOptions {
|
|
37
|
+
resolveRuntime?: (siteOrigin: string) => Promise<ProspectusSignInRuntime | null>;
|
|
38
|
+
siteProduct?: string | null;
|
|
39
|
+
completionOverrides?: Pick<CompleteProspectusGoogleSignInInput, "verifyCognitoTokens" | "fetcher">;
|
|
40
|
+
nowInSeconds?: () => number;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const NO_STORE_HEADERS = { "cache-control": "no-store" };
|
|
44
|
+
|
|
45
|
+
function siteProductFor(options: ProspectusSignInRouteOptions): string | null {
|
|
46
|
+
return options.siteProduct !== undefined ? options.siteProduct : prospectusSiteProduct();
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function currentTimeInSeconds(options: ProspectusSignInRouteOptions): number {
|
|
50
|
+
return options.nowInSeconds?.() ?? Math.floor(Date.now() / 1000);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
async function signInRuntimeFor(request: NextRequest, options: ProspectusSignInRouteOptions): Promise<ProspectusSignInRuntime | null> {
|
|
54
|
+
return (options.resolveRuntime ?? resolveProspectusSignInRuntime)(request.nextUrl.origin);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function signInUnavailableResponse(): NextResponse {
|
|
58
|
+
return NextResponse.json(
|
|
59
|
+
{ error: "prospectus_sign_in_unavailable", message: "Sign-in through Prospectus is not configured for this site." },
|
|
60
|
+
{ status: 503, headers: NO_STORE_HEADERS },
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function clearSealedCookie(response: NextResponse, cookieName: string): void {
|
|
65
|
+
response.cookies.set(cookieName, "", sealedCookieAttributes(0, 0));
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function signInFailedResponse(status: number, code: string, message: string): NextResponse {
|
|
69
|
+
return NextResponse.json({ error: code, message }, { status, headers: NO_STORE_HEADERS });
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export function signedInProspectusSession(
|
|
73
|
+
request: NextRequest,
|
|
74
|
+
sealingSecret: string,
|
|
75
|
+
nowInSeconds?: number,
|
|
76
|
+
): ProspectusSignedInSession | null {
|
|
77
|
+
return openProspectusCookie<ProspectusSignedInSession>(
|
|
78
|
+
sealingSecret,
|
|
79
|
+
PROSPECTUS_SESSION_COOKIE,
|
|
80
|
+
request.cookies.get(PROSPECTUS_SESSION_COOKIE)?.value,
|
|
81
|
+
nowInSeconds,
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export async function handleProspectusSignInStart(request: NextRequest, options: ProspectusSignInRouteOptions = {}): Promise<NextResponse> {
|
|
86
|
+
const runtime = await signInRuntimeFor(request, options);
|
|
87
|
+
if (!runtime) return signInUnavailableResponse();
|
|
88
|
+
const { authorizationUrl, pendingSignIn } = await beginProspectusGoogleSignIn(runtime.accounts, runtime.cognitoClient);
|
|
89
|
+
const pendingSignInCookie: PendingProspectusSignInCookie = {
|
|
90
|
+
...pendingSignIn,
|
|
91
|
+
returnPath: sameSiteReturnPath(request.nextUrl.searchParams.get("returnTo")),
|
|
92
|
+
};
|
|
93
|
+
const response = NextResponse.redirect(authorizationUrl, { status: 303, headers: NO_STORE_HEADERS });
|
|
94
|
+
response.cookies.set(
|
|
95
|
+
PROSPECTUS_PENDING_SIGN_IN_COOKIE,
|
|
96
|
+
sealProspectusCookie(runtime.sealingSecret, PROSPECTUS_PENDING_SIGN_IN_COOKIE, pendingSignInCookie, pendingSignIn.expiresAt),
|
|
97
|
+
sealedCookieAttributes(pendingSignIn.expiresAt, currentTimeInSeconds(options)),
|
|
98
|
+
);
|
|
99
|
+
return response;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export async function handleProspectusSignInCallback(request: NextRequest, options: ProspectusSignInRouteOptions = {}): Promise<NextResponse> {
|
|
103
|
+
const runtime = await signInRuntimeFor(request, options);
|
|
104
|
+
if (!runtime) return signInUnavailableResponse();
|
|
105
|
+
const nowInSeconds = currentTimeInSeconds(options);
|
|
106
|
+
const pendingSignIn = openProspectusCookie<PendingProspectusSignInCookie>(
|
|
107
|
+
runtime.sealingSecret,
|
|
108
|
+
PROSPECTUS_PENDING_SIGN_IN_COOKIE,
|
|
109
|
+
request.cookies.get(PROSPECTUS_PENDING_SIGN_IN_COOKIE)?.value,
|
|
110
|
+
nowInSeconds,
|
|
111
|
+
);
|
|
112
|
+
const response = await completeCallback(request, runtime, pendingSignIn, options, nowInSeconds);
|
|
113
|
+
clearSealedCookie(response, PROSPECTUS_PENDING_SIGN_IN_COOKIE);
|
|
114
|
+
return response;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
async function completeCallback(
|
|
118
|
+
request: NextRequest,
|
|
119
|
+
runtime: ProspectusSignInRuntime,
|
|
120
|
+
pendingSignIn: PendingProspectusSignInCookie | null,
|
|
121
|
+
options: ProspectusSignInRouteOptions,
|
|
122
|
+
nowInSeconds: number,
|
|
123
|
+
): Promise<NextResponse> {
|
|
124
|
+
if (!pendingSignIn) return signInFailedResponse(401, "sign_in_expired", "This sign-in is no longer pending. Start again.");
|
|
125
|
+
const searchParams = request.nextUrl.searchParams;
|
|
126
|
+
if (searchParams.get("error")) return signInFailedResponse(401, "sign_in_declined", "Google sign-in did not complete.");
|
|
127
|
+
const authorizationCode = searchParams.get("code");
|
|
128
|
+
const returnedState = searchParams.get("state");
|
|
129
|
+
if (!authorizationCode || !returnedState) return signInFailedResponse(400, "sign_in_incomplete", "The sign-in response is missing its code or state.");
|
|
130
|
+
try {
|
|
131
|
+
const signedIn = await completeProspectusGoogleSignIn({
|
|
132
|
+
accounts: runtime.accounts,
|
|
133
|
+
cognitoClient: runtime.cognitoClient,
|
|
134
|
+
pendingSignIn,
|
|
135
|
+
returnedState,
|
|
136
|
+
authorizationCode,
|
|
137
|
+
nowInSeconds,
|
|
138
|
+
...options.completionOverrides,
|
|
139
|
+
});
|
|
140
|
+
const session: ProspectusSignedInSession = {
|
|
141
|
+
personId: signedIn.person.id,
|
|
142
|
+
accessToken: signedIn.accessToken,
|
|
143
|
+
accessTokenExpiresAt: signedIn.accessTokenExpiresAt,
|
|
144
|
+
};
|
|
145
|
+
const response = NextResponse.redirect(new URL(pendingSignIn.returnPath, request.nextUrl.origin), { status: 303, headers: NO_STORE_HEADERS });
|
|
146
|
+
response.cookies.set(
|
|
147
|
+
PROSPECTUS_SESSION_COOKIE,
|
|
148
|
+
sealProspectusCookie(runtime.sealingSecret, PROSPECTUS_SESSION_COOKIE, session, session.accessTokenExpiresAt),
|
|
149
|
+
sealedCookieAttributes(session.accessTokenExpiresAt, nowInSeconds),
|
|
150
|
+
);
|
|
151
|
+
return response;
|
|
152
|
+
} catch (error) {
|
|
153
|
+
if (error instanceof ProspectusAccountsError) return signInFailedResponse(error.status, error.code, error.message);
|
|
154
|
+
console.error(`Prospectus sign-in failed (${error instanceof Error ? error.name : "error"}).`);
|
|
155
|
+
return signInFailedResponse(401, "sign_in_failed", "Sign-in could not be completed.");
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export async function handleProspectusSessionRead(request: NextRequest, options: ProspectusSignInRouteOptions = {}): Promise<NextResponse> {
|
|
160
|
+
const runtime = await signInRuntimeFor(request, options);
|
|
161
|
+
if (!runtime) return signInUnavailableResponse();
|
|
162
|
+
const session = signedInProspectusSession(request, runtime.sealingSecret, currentTimeInSeconds(options));
|
|
163
|
+
if (!session) return NextResponse.json({ signedIn: false }, { headers: NO_STORE_HEADERS });
|
|
164
|
+
try {
|
|
165
|
+
const directory = await runtime.accounts.accountDirectory(session.accessToken);
|
|
166
|
+
if (!directory.person || directory.person.id !== session.personId) {
|
|
167
|
+
const response = NextResponse.json({ signedIn: false }, { headers: NO_STORE_HEADERS });
|
|
168
|
+
clearSealedCookie(response, PROSPECTUS_SESSION_COOKIE);
|
|
169
|
+
return response;
|
|
170
|
+
}
|
|
171
|
+
const publishingAccounts = publishingAccountsForSite(directory.accounts, siteProductFor(options));
|
|
172
|
+
return NextResponse.json(
|
|
173
|
+
{
|
|
174
|
+
signedIn: true,
|
|
175
|
+
person: directory.person,
|
|
176
|
+
accounts: directory.accounts,
|
|
177
|
+
cyclotronLabAccess: directory.accounts.some((account) =>
|
|
178
|
+
account.products.some((product) => product.product === CYCLOTRON_LAB_PRODUCT && product.status === "active"),
|
|
179
|
+
),
|
|
180
|
+
publishingAccounts,
|
|
181
|
+
selectedAccountId: publishingAccounts.some((account) => account.accountId === session.selectedAccountId)
|
|
182
|
+
? session.selectedAccountId
|
|
183
|
+
: null,
|
|
184
|
+
},
|
|
185
|
+
{ headers: NO_STORE_HEADERS },
|
|
186
|
+
);
|
|
187
|
+
} catch (error) {
|
|
188
|
+
if (error instanceof ProspectusAccountsError && error.status === 401) {
|
|
189
|
+
const response = NextResponse.json({ signedIn: false }, { headers: NO_STORE_HEADERS });
|
|
190
|
+
clearSealedCookie(response, PROSPECTUS_SESSION_COOKIE);
|
|
191
|
+
return response;
|
|
192
|
+
}
|
|
193
|
+
if (error instanceof ProspectusAccountsError) return signInFailedResponse(error.status, error.code, error.message);
|
|
194
|
+
console.error(`Prospectus account directory failed (${error instanceof Error ? error.name : "error"}).`);
|
|
195
|
+
return signInFailedResponse(503, "prospectus_unavailable", "Prospectus could not be reached.");
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
export async function handleProspectusSignOut(request: NextRequest, options: ProspectusSignInRouteOptions = {}): Promise<NextResponse> {
|
|
200
|
+
const runtime = await signInRuntimeFor(request, options);
|
|
201
|
+
const signedOutDestination = new URL("/", request.nextUrl.origin);
|
|
202
|
+
const destination = runtime
|
|
203
|
+
? new URL(
|
|
204
|
+
`/logout?${new URLSearchParams({ client_id: runtime.cognitoClient.clientId, logout_uri: signedOutDestination.toString() })}`,
|
|
205
|
+
runtime.cognitoClient.hostedUiOrigin,
|
|
206
|
+
)
|
|
207
|
+
: signedOutDestination;
|
|
208
|
+
const response = NextResponse.redirect(destination, { status: 303, headers: NO_STORE_HEADERS });
|
|
209
|
+
clearSealedCookie(response, PROSPECTUS_SESSION_COOKIE);
|
|
210
|
+
clearSealedCookie(response, PROSPECTUS_PENDING_SIGN_IN_COOKIE);
|
|
211
|
+
return response;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
export interface ProspectusPublishingSelection {
|
|
215
|
+
personId: string;
|
|
216
|
+
accountId: string;
|
|
217
|
+
role: string;
|
|
218
|
+
publicationCapabilities: PublicationCapability[];
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
async function freshlyAuthorizedPublishingSelection(
|
|
222
|
+
runtime: ProspectusSignInRuntime,
|
|
223
|
+
session: ProspectusSignedInSession,
|
|
224
|
+
accountId: string,
|
|
225
|
+
siteProduct: string | null,
|
|
226
|
+
): Promise<ProspectusPublishingSelection | null> {
|
|
227
|
+
const directory = await runtime.accounts.accountDirectory(session.accessToken);
|
|
228
|
+
if (!directory.person || directory.person.id !== session.personId) return null;
|
|
229
|
+
if (!publishingAccountsForSite(directory.accounts, siteProduct).some((account) => account.accountId === accountId)) return null;
|
|
230
|
+
const authorization = await authorizeSignedInPersonForAccount(runtime.accounts, session.accessToken, accountId, "console:read");
|
|
231
|
+
if (authorization.personId !== session.personId) return null;
|
|
232
|
+
const publicationCapabilities = publicationCapabilitiesForProspectusRole(authorization.role);
|
|
233
|
+
if (publicationCapabilities.length === 0) return null;
|
|
234
|
+
return { personId: session.personId, accountId, role: authorization.role, publicationCapabilities };
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
export async function currentProspectusPublishingSelection(
|
|
238
|
+
request: NextRequest,
|
|
239
|
+
options: ProspectusSignInRouteOptions = {},
|
|
240
|
+
): Promise<ProspectusPublishingSelection | null> {
|
|
241
|
+
const runtime = await signInRuntimeFor(request, options);
|
|
242
|
+
if (!runtime) return null;
|
|
243
|
+
const session = signedInProspectusSession(request, runtime.sealingSecret, currentTimeInSeconds(options));
|
|
244
|
+
if (!session?.selectedAccountId) return null;
|
|
245
|
+
try {
|
|
246
|
+
return await freshlyAuthorizedPublishingSelection(runtime, session, session.selectedAccountId, siteProductFor(options));
|
|
247
|
+
} catch (error) {
|
|
248
|
+
if (error instanceof ProspectusAccountsError) return null;
|
|
249
|
+
throw error;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
export async function handleProspectusAccountSelection(request: NextRequest, options: ProspectusSignInRouteOptions = {}): Promise<NextResponse> {
|
|
254
|
+
const runtime = await signInRuntimeFor(request, options);
|
|
255
|
+
if (!runtime) return signInUnavailableResponse();
|
|
256
|
+
if (request.headers.get("origin") !== request.nextUrl.origin) {
|
|
257
|
+
return signInFailedResponse(403, "cross_origin_selection", "Choose an account from this site.");
|
|
258
|
+
}
|
|
259
|
+
const nowInSeconds = currentTimeInSeconds(options);
|
|
260
|
+
const session = signedInProspectusSession(request, runtime.sealingSecret, nowInSeconds);
|
|
261
|
+
if (!session) return signInFailedResponse(401, "signed_out", "Sign in first.");
|
|
262
|
+
const body = await request.json().catch(() => null) as { accountId?: unknown } | null;
|
|
263
|
+
const accountId = typeof body?.accountId === "string" ? body.accountId.trim() : "";
|
|
264
|
+
if (!accountId) return signInFailedResponse(400, "account_required", "Choose an account.");
|
|
265
|
+
try {
|
|
266
|
+
const selection = await freshlyAuthorizedPublishingSelection(runtime, session, accountId, siteProductFor(options));
|
|
267
|
+
if (!selection) return signInFailedResponse(403, "not_a_publishing_account", "You cannot work on this site's publications in that account.");
|
|
268
|
+
const response = NextResponse.json(
|
|
269
|
+
{ selectedAccountId: selection.accountId, role: selection.role, publicationCapabilities: selection.publicationCapabilities },
|
|
270
|
+
{ headers: NO_STORE_HEADERS },
|
|
271
|
+
);
|
|
272
|
+
const selectedSession: ProspectusSignedInSession = { ...session, selectedAccountId: selection.accountId };
|
|
273
|
+
response.cookies.set(
|
|
274
|
+
PROSPECTUS_SESSION_COOKIE,
|
|
275
|
+
sealProspectusCookie(runtime.sealingSecret, PROSPECTUS_SESSION_COOKIE, selectedSession, session.accessTokenExpiresAt),
|
|
276
|
+
sealedCookieAttributes(session.accessTokenExpiresAt, nowInSeconds),
|
|
277
|
+
);
|
|
278
|
+
return response;
|
|
279
|
+
} catch (error) {
|
|
280
|
+
if (error instanceof ProspectusAccountsError) return signInFailedResponse(error.status, error.code, error.message);
|
|
281
|
+
console.error(`Prospectus account selection failed (${error instanceof Error ? error.name : "error"}).`);
|
|
282
|
+
return signInFailedResponse(503, "prospectus_unavailable", "Prospectus could not be reached.");
|
|
283
|
+
}
|
|
284
|
+
}
|
package/lib/site-brand.ts
CHANGED
|
@@ -64,6 +64,19 @@ export type SiteBrandVideo = {
|
|
|
64
64
|
rhythm?: Record<string, unknown>;
|
|
65
65
|
};
|
|
66
66
|
|
|
67
|
+
/**
|
|
68
|
+
* The publication's name for its one content item. A content item keeps one
|
|
69
|
+
* identity and one lifecycle from idea through research, reporting,
|
|
70
|
+
* copywriting and publication; only the word editors see changes per
|
|
71
|
+
* publication (for example Story, Article or Post).
|
|
72
|
+
*/
|
|
73
|
+
export type ContentItemName = {
|
|
74
|
+
singular: string;
|
|
75
|
+
plural: string;
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
export const DEFAULT_CONTENT_ITEM_NAME: ContentItemName = { singular: "Story", plural: "Stories" };
|
|
79
|
+
|
|
67
80
|
export type SiteBrand = {
|
|
68
81
|
id: SiteBrandId;
|
|
69
82
|
appTitle: string;
|
|
@@ -77,6 +90,8 @@ export type SiteBrand = {
|
|
|
77
90
|
mastheadTaglineLines?: SiteBrandTaglineLine[];
|
|
78
91
|
backToHomeLabel: string;
|
|
79
92
|
articleTitleSuffix: string;
|
|
93
|
+
/** Defaults to Story / Stories, the newsroom term. */
|
|
94
|
+
contentItemName?: ContentItemName;
|
|
80
95
|
placeholderByline: string;
|
|
81
96
|
defaultPresentation: EditionPresentationFormat;
|
|
82
97
|
forcedPresentation?: EditionPresentationFormat;
|
|
@@ -204,6 +219,10 @@ export function getSiteBrand(id: SiteBrandId = resolveSiteBrandId()): SiteBrand
|
|
|
204
219
|
|
|
205
220
|
export const SITE_BRAND = getSiteBrand();
|
|
206
221
|
|
|
222
|
+
export function getContentItemName(brand: SiteBrand = SITE_BRAND): ContentItemName {
|
|
223
|
+
return brand.contentItemName ?? DEFAULT_CONTENT_ITEM_NAME;
|
|
224
|
+
}
|
|
225
|
+
|
|
207
226
|
/** Root-route config for a brand, defaulting to `{ kind: "reader" }`. */
|
|
208
227
|
export function getRootRoute(brand: SiteBrand = SITE_BRAND): RootRouteConfig {
|
|
209
228
|
return brand.rootRoute ?? { kind: "reader" };
|
package/package.json
CHANGED
|
@@ -155,6 +155,7 @@
|
|
|
155
155
|
"./lib/console-web-context": "./lib/console-web-context.ts",
|
|
156
156
|
"./lib/content-actions-client": "./lib/content-actions-client.ts",
|
|
157
157
|
"./lib/content-actions-demo": "./lib/content-actions-demo.ts",
|
|
158
|
+
"./lib/content-item-lifecycle": "./lib/content-item-lifecycle.ts",
|
|
158
159
|
"./lib/content-load-timing": "./lib/content-load-timing.ts",
|
|
159
160
|
"./lib/content-repository": "./lib/content-repository.ts",
|
|
160
161
|
"./lib/content-source-context": "./lib/content-source-context.ts",
|
|
@@ -208,6 +209,9 @@
|
|
|
208
209
|
"./lib/presentation-footer": "./lib/presentation-footer.ts",
|
|
209
210
|
"./lib/pretext-layout": "./lib/pretext-layout.ts",
|
|
210
211
|
"./lib/priming-proof-report": "./lib/priming-proof-report.ts",
|
|
212
|
+
"./lib/prospectus-publication-access": "./lib/prospectus-publication-access.ts",
|
|
213
|
+
"./lib/prospectus-session": "./lib/prospectus-session.ts",
|
|
214
|
+
"./lib/prospectus-sign-in-routes": "./lib/prospectus-sign-in-routes.ts",
|
|
211
215
|
"./lib/prospectus-site-identity": "./lib/prospectus-site-identity.ts",
|
|
212
216
|
"./lib/public-placeholder-config": "./lib/public-placeholder-config.ts",
|
|
213
217
|
"./lib/publication-cyclotron": "./lib/publication-cyclotron.ts",
|
|
@@ -263,6 +267,11 @@
|
|
|
263
267
|
"./app/[year]/[month]/[day]/page/[pageNumber]/page": "./app/[year]/[month]/[day]/page/[pageNumber]/page.tsx",
|
|
264
268
|
"./app/[year]/[month]/[day]/section/[sectionKey]/page": "./app/[year]/[month]/[day]/section/[sectionKey]/page.tsx",
|
|
265
269
|
"./app/api/archive/editions/route": "./app/api/archive/editions/route.ts",
|
|
270
|
+
"./app/api/auth/prospectus/callback/route": "./app/api/auth/prospectus/callback/route.ts",
|
|
271
|
+
"./app/api/auth/prospectus/selection/route": "./app/api/auth/prospectus/selection/route.ts",
|
|
272
|
+
"./app/api/auth/prospectus/session/route": "./app/api/auth/prospectus/session/route.ts",
|
|
273
|
+
"./app/api/auth/prospectus/sign-in/route": "./app/api/auth/prospectus/sign-in/route.ts",
|
|
274
|
+
"./app/api/auth/prospectus/sign-out/route": "./app/api/auth/prospectus/sign-out/route.ts",
|
|
266
275
|
"./app/api/cyclotron/priming-proof/route": "./app/api/cyclotron/priming-proof/route.ts",
|
|
267
276
|
"./app/api/media/[...path]/route": "./app/api/media/[...path]/route.ts",
|
|
268
277
|
"./app/api/revalidate/route": "./app/api/revalidate/route.ts",
|
|
@@ -331,13 +340,14 @@
|
|
|
331
340
|
"optional": true
|
|
332
341
|
}
|
|
333
342
|
},
|
|
334
|
-
"version": "1.0.0-next.
|
|
343
|
+
"version": "1.0.0-next.64",
|
|
335
344
|
"dependencies": {
|
|
336
345
|
"@aws-amplify/adapter-nextjs": "^1.7.3",
|
|
337
346
|
"@aws-crypto/sha256-js": "5.2.0",
|
|
338
347
|
"@aws-sdk/client-cognito-identity-provider": "3.1045.0",
|
|
339
348
|
"@aws-sdk/client-lambda": "^3.1045.0",
|
|
340
349
|
"@aws-sdk/client-s3": "^3.1045.0",
|
|
350
|
+
"@aws-sdk/client-secrets-manager": "3.1045.0",
|
|
341
351
|
"@aws-sdk/client-ssm": "^3.1045.0",
|
|
342
352
|
"@aws-sdk/credential-provider-node": "3.972.84",
|
|
343
353
|
"@aws-sdk/s3-request-presigner": "^3.1045.0",
|
package/routes.manifest.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "1.0.0-next.
|
|
2
|
+
"version": "1.0.0-next.64",
|
|
3
3
|
"routes": [
|
|
4
4
|
{
|
|
5
5
|
"file": "app/%5F_preview/[[...path]]/route.ts",
|
|
@@ -66,6 +66,61 @@
|
|
|
66
66
|
"revalidate": "60"
|
|
67
67
|
}
|
|
68
68
|
},
|
|
69
|
+
{
|
|
70
|
+
"file": "app/api/auth/prospectus/callback/route.ts",
|
|
71
|
+
"hasDefault": false,
|
|
72
|
+
"exports": [
|
|
73
|
+
"GET"
|
|
74
|
+
],
|
|
75
|
+
"config": {
|
|
76
|
+
"dynamic": "\"force-dynamic\"",
|
|
77
|
+
"runtime": "\"nodejs\""
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
"file": "app/api/auth/prospectus/selection/route.ts",
|
|
82
|
+
"hasDefault": false,
|
|
83
|
+
"exports": [
|
|
84
|
+
"POST"
|
|
85
|
+
],
|
|
86
|
+
"config": {
|
|
87
|
+
"dynamic": "\"force-dynamic\"",
|
|
88
|
+
"runtime": "\"nodejs\""
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
"file": "app/api/auth/prospectus/session/route.ts",
|
|
93
|
+
"hasDefault": false,
|
|
94
|
+
"exports": [
|
|
95
|
+
"GET"
|
|
96
|
+
],
|
|
97
|
+
"config": {
|
|
98
|
+
"dynamic": "\"force-dynamic\"",
|
|
99
|
+
"runtime": "\"nodejs\""
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
"file": "app/api/auth/prospectus/sign-in/route.ts",
|
|
104
|
+
"hasDefault": false,
|
|
105
|
+
"exports": [
|
|
106
|
+
"GET"
|
|
107
|
+
],
|
|
108
|
+
"config": {
|
|
109
|
+
"dynamic": "\"force-dynamic\"",
|
|
110
|
+
"runtime": "\"nodejs\""
|
|
111
|
+
}
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
"file": "app/api/auth/prospectus/sign-out/route.ts",
|
|
115
|
+
"hasDefault": false,
|
|
116
|
+
"exports": [
|
|
117
|
+
"POST"
|
|
118
|
+
],
|
|
119
|
+
"config": {
|
|
120
|
+
"dynamic": "\"force-dynamic\"",
|
|
121
|
+
"runtime": "\"nodejs\""
|
|
122
|
+
}
|
|
123
|
+
},
|
|
69
124
|
{
|
|
70
125
|
"file": "app/api/cyclotron/priming-proof/route.ts",
|
|
71
126
|
"hasDefault": false,
|