@jwilleke/ngdpbase-types 5.39.0 → 5.41.0
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/lib/packages/ngdpbase-types/index.d.ts +1 -1
- package/lib/src/context/ApiContext.d.ts +3 -2
- package/lib/src/context/ApiContext.js +4 -2
- package/lib/src/ice/fileHandling.d.ts +6 -1
- package/lib/src/ice/givenName.d.ts +19 -0
- package/lib/src/ice/runExport.d.ts +41 -0
- package/lib/src/ice/runImport.d.ts +37 -8
- package/lib/src/ice/shims/csv.d.ts +24 -0
- package/lib/src/ice/shims/export.d.ts +23 -0
- package/lib/src/ice/shims/index.d.ts +3 -1
- package/lib/src/ice/shims/svg.d.ts +27 -0
- package/lib/src/ice/shims/takeout.d.ts +83 -0
- package/lib/src/ice/types.d.ts +301 -5
- package/lib/src/ice/vet.d.ts +19 -0
- package/lib/src/managers/AttachmentManager.d.ts +100 -36
- package/lib/src/managers/AuthManager.d.ts +152 -12
- package/lib/src/managers/AuthManager.js +3830 -0
- package/lib/src/managers/BackgroundJobManager.d.ts +25 -0
- package/lib/src/managers/BackupManager.d.ts +24 -0
- package/lib/src/managers/BackupManager.js +48 -1
- package/lib/src/managers/ExportManager.d.ts +16 -0
- package/lib/src/managers/ExportManager.js +25 -0
- package/lib/src/managers/FileManager.d.ts +182 -0
- package/lib/src/managers/ImportManager.d.ts +279 -16
- package/lib/src/managers/MediaManager.d.ts +2 -0
- package/lib/src/managers/PageManager.d.ts +53 -0
- package/lib/src/managers/SearchManager.d.ts +4 -0
- package/lib/src/managers/SharedFolderManager.d.ts +320 -0
- package/lib/src/managers/ValidationManager.d.ts +5 -2
- package/lib/src/middleware/csrf.js +99 -0
- package/lib/src/providers/AgentTokenAuthProvider.js +46 -0
- package/lib/src/providers/AuthentikBearerAuthProvider.js +176 -0
- package/lib/src/providers/BaseCredentialsProvider.js +21 -0
- package/lib/src/providers/BaseMediaProvider.d.ts +4 -0
- package/lib/src/providers/BasePageProvider.d.ts +8 -0
- package/lib/src/providers/CloudflareAccessAuthProvider.js +160 -0
- package/lib/src/providers/FileCredentialsProvider.js +188 -0
- package/lib/src/providers/FileSystemMediaProvider.d.ts +6 -0
- package/lib/src/providers/MagicLinkAuthProvider.js +333 -0
- package/lib/src/providers/OidcAuthProvider.js +350 -0
- package/lib/src/providers/OidcBearerAuthProvider.js +27 -0
- package/lib/src/providers/PasskeyAuthProvider.js +147 -0
- package/lib/src/providers/PasswordAuthProvider.js +44 -0
- package/lib/src/security/PolicyDecisionPoint.d.ts +3 -2
- package/lib/src/security/pageActions.js +43 -0
- package/lib/src/security/permissions.generated.d.ts +7 -3
- package/lib/src/types/File.d.ts +90 -0
- package/lib/src/types/Provider.d.ts +15 -0
- package/lib/src/types/express.d.ts +7 -1
- package/lib/src/types/guards.js +366 -0
- package/lib/src/types/linkedom.d.ts +2 -0
- package/lib/src/utils/atomicWrite.js +129 -0
- package/lib/src/utils/auditEventNames.generated.d.ts +12 -0
- package/lib/src/utils/auditEventNames.generated.js +12 -0
- package/lib/src/utils/auditEvents.d.ts +15 -0
- package/lib/src/utils/auditEvents.js +17 -1
- package/lib/src/utils/bip39English.js +2 -0
- package/lib/src/utils/browserDescription.js +28 -0
- package/lib/src/utils/delegation.js +79 -0
- package/lib/src/utils/deriveUsername.js +38 -0
- package/lib/src/utils/emailForLog.js +28 -0
- package/lib/src/utils/fileMigrationPlan.d.ts +81 -0
- package/lib/src/utils/instanceEnvBackup.d.ts +6 -0
- package/lib/src/utils/instanceEnvBackup.js +13 -0
- package/lib/src/utils/ipLocation.js +106 -0
- package/lib/src/utils/magicLinkDeviceState.js +97 -0
- package/lib/src/utils/pageUrl.d.ts +1 -0
- package/lib/src/utils/passwordHash.js +150 -0
- package/lib/src/utils/permissionCatalog.js +102 -0
- package/lib/src/utils/privateStoreAccess.d.ts +25 -0
- package/lib/src/utils/privateStoreAccess.js +22 -1
- package/lib/src/utils/privateStoreCatalogs.js +57 -0
- package/lib/src/utils/privateStoreCrypto.js +266 -0
- package/lib/src/utils/privateStoreDoor.d.ts +10 -0
- package/lib/src/utils/privateStoreDoor.js +298 -0
- package/lib/src/utils/privateStoreImport.d.ts +0 -10
- package/lib/src/utils/privateStoreMeta.js +123 -0
- package/lib/src/utils/privateStorePath.d.ts +37 -1
- package/lib/src/utils/privateStorePath.js +60 -3
- package/lib/src/utils/privateStoreTakeout.js +149 -0
- package/lib/src/utils/privateStoreUnlock.d.ts +3 -0
- package/lib/src/utils/privateStoreUnlock.js +499 -0
- package/lib/src/utils/recoveryWordsFile.d.ts +54 -0
- package/lib/src/utils/safeRedirect.js +55 -0
- package/lib/src/utils/sessionAccount.js +55 -0
- package/lib/src/utils/sessionEnd.d.ts +1 -0
- package/lib/src/utils/sessionEnd.js +42 -0
- package/lib/src/utils/sessionGeneration.js +29 -0
- package/lib/src/utils/sessionIdle.d.ts +4 -0
- package/lib/src/utils/sessionIdle.js +72 -0
- package/lib/src/utils/sessionLimits.js +72 -0
- package/lib/src/utils/sessionSecurity.js +122 -0
- package/lib/src/utils/shareLockbox.js +101 -0
- package/lib/src/utils/sharedFolderAccess.d.ts +57 -0
- package/lib/src/utils/sharedFolderAccess.js +80 -0
- package/lib/src/utils/userCreateError.js +82 -0
- package/lib/src/utils/username.d.ts +2 -0
- package/lib/src/utils/username.js +105 -0
- package/package.json +2 -1
|
@@ -32,7 +32,8 @@ import type { WikiEngine } from '../types/WikiEngine.js';
|
|
|
32
32
|
import { IContentConverter } from '../converters/IContentConverter.js';
|
|
33
33
|
import { type ZipReadLimits } from '../utils/zipArchive.js';
|
|
34
34
|
import { type JobContext } from '../context/JobContext.js';
|
|
35
|
-
import
|
|
35
|
+
import { type IceNameForm } from '../ice/givenName.js';
|
|
36
|
+
import type { IceExportFormat, IceExportReport, IceExportRequest, IceExportSource, IceLedger, IceOriginalChoices, IceReceiver, IceRunReport, IceRunRequest, IceShim, IceTarget, IceUpload, IceVetResult, RecentImport, RegisteredShim } from '../ice/types.js';
|
|
36
37
|
/**
|
|
37
38
|
* Options for import operations
|
|
38
39
|
*/
|
|
@@ -217,6 +218,31 @@ export declare class ImportUploadRefused extends Error {
|
|
|
217
218
|
readonly reason: string;
|
|
218
219
|
constructor(file: string, reason: string);
|
|
219
220
|
}
|
|
221
|
+
/**
|
|
222
|
+
* An export that is not started (#2120): the thing is not there, the user may
|
|
223
|
+
* not export it, or the format is not one offered for it. A route answers it
|
|
224
|
+
* as "not found", so it never tells the user which.
|
|
225
|
+
*/
|
|
226
|
+
export declare class IceExportRefused extends Error {
|
|
227
|
+
constructor(message?: string);
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* An export not started because too much is already being made (#2120): the
|
|
231
|
+
* user's own queued exports are at `max-queued-per-user`, or every held run is
|
|
232
|
+
* still being made. A route answers it as 429; nothing was read or queued.
|
|
233
|
+
*/
|
|
234
|
+
export declare class IceExportBusy extends Error {
|
|
235
|
+
constructor(message: string);
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* An export refused only because the user's sign-in is not fresh enough
|
|
239
|
+
* (#2120): they hold `permission` on the thing, and step-up asks for it. A
|
|
240
|
+
* route answers it with the step-up prompt, not "not found".
|
|
241
|
+
*/
|
|
242
|
+
export declare class IceExportNeedsFreshSignIn extends Error {
|
|
243
|
+
readonly permission: string;
|
|
244
|
+
constructor(permission: string);
|
|
245
|
+
}
|
|
220
246
|
/** One page's outcome in a takeout import (#1472). */
|
|
221
247
|
export type TakeoutPageOutcome = {
|
|
222
248
|
title: string;
|
|
@@ -269,13 +295,13 @@ export interface UsableReceiver {
|
|
|
269
295
|
label?: string;
|
|
270
296
|
/** What the screen offers; the kept types (`types`, #2061) are the upload door's business, not the screen's. */
|
|
271
297
|
originals: Required<Omit<IceOriginalChoices, 'types'>>;
|
|
298
|
+
/** What a name the user gives becomes (#2130), when the receiver takes one: the screen offers the field only then. */
|
|
299
|
+
names?: IceNameForm;
|
|
300
|
+
/** Where within it this user may import (#2118), for a receiver with places: the screen offers a choice of them. */
|
|
301
|
+
targets?: IceTarget[];
|
|
272
302
|
}
|
|
273
|
-
/**
|
|
274
|
-
* Import Manager class
|
|
275
|
-
*
|
|
276
|
-
* Manages content import with extensible format support via converter registry.
|
|
277
|
-
*/
|
|
278
303
|
declare class ImportManager extends BaseManager {
|
|
304
|
+
#private;
|
|
279
305
|
/** Registry of format converters */
|
|
280
306
|
private converterRegistry;
|
|
281
307
|
/** ICE (#1979): shims by id (`<owner>.<name>`), in registration order. */
|
|
@@ -284,13 +310,19 @@ declare class ImportManager extends BaseManager {
|
|
|
284
310
|
private readonly receiverRegistry;
|
|
285
311
|
/** ICE: runs this process knows about, oldest first. */
|
|
286
312
|
private readonly iceRuns;
|
|
287
|
-
/** ICE:
|
|
313
|
+
/** ICE (#2171): a rechecking run's store, as fingerprint → id, read once per run and store; dropped when the run ends. */
|
|
314
|
+
private readonly storeHoldings;
|
|
315
|
+
/** ICE: work waiting for the background job, each with its own context: an import run or an export (#2120). */
|
|
288
316
|
private readonly iceQueue;
|
|
289
317
|
/** ICE: true while a background job is draining the queue. */
|
|
290
318
|
private iceDraining;
|
|
291
319
|
/** ICE: the last background run id the queue was handed to. */
|
|
292
320
|
private iceLastJobRunId;
|
|
293
321
|
private iceLedger;
|
|
322
|
+
/** ICE export (#2120): the owners' doors for reading what is exported, by id. */
|
|
323
|
+
private readonly exportSourceRegistry;
|
|
324
|
+
/** ICE export: runs this process holds, oldest first, each with its file once made. Never written to disk. */
|
|
325
|
+
private readonly exportRuns;
|
|
294
326
|
constructor(engine: WikiEngine);
|
|
295
327
|
/**
|
|
296
328
|
* Initialize the manager
|
|
@@ -316,7 +348,9 @@ declare class ImportManager extends BaseManager {
|
|
|
316
348
|
/**
|
|
317
349
|
* Register a receiver (D4): a door that already exists. Core's are
|
|
318
350
|
* `core.pages` and `core.files`; an add-on registers its own manager's door
|
|
319
|
-
* through `host.registerReceiver`.
|
|
351
|
+
* through `host.registerReceiver`. Refuses `writesEncrypted` from every
|
|
352
|
+
* caller, whatever owner it names: core registers its own receivers
|
|
353
|
+
* through the private `#registerReceiver` (#2179).
|
|
320
354
|
*
|
|
321
355
|
* @returns The receiver's id, `<owner>.<name>`
|
|
322
356
|
*/
|
|
@@ -333,18 +367,49 @@ declare class ImportManager extends BaseManager {
|
|
|
333
367
|
* (D11), for the import screen (#2021).
|
|
334
368
|
*/
|
|
335
369
|
receiversFor(ctx: ActorContext): Promise<UsableReceiver[]>;
|
|
370
|
+
/**
|
|
371
|
+
* Why a name the user gave cannot be used for this receiver (#2130), or
|
|
372
|
+
* null when it can: the engine's one rule (`givenNameProblem`), with the
|
|
373
|
+
* site's `ngdpbase.import.engine.name-max-length`. A receiver that names
|
|
374
|
+
* what it creates itself (no `names`) takes no name at all. For the import
|
|
375
|
+
* screen, to answer at once; the engine checks again in the run.
|
|
376
|
+
*/
|
|
377
|
+
givenNameProblem(receiverId: string, given: string, original: string): string | null;
|
|
336
378
|
/**
|
|
337
379
|
* The original-file choices a receiver offers (D11, #2021): what it
|
|
338
380
|
* declares, else all three; its default when it names one it allows, else
|
|
339
381
|
* `ngdpbase.import.engine.default-original` when allowed, else the first.
|
|
340
382
|
*/
|
|
341
383
|
private originalChoices;
|
|
384
|
+
/**
|
|
385
|
+
* The request's place within the receiver, checked (#2118): one the
|
|
386
|
+
* receiver's `targets` gives this context, for a receiver with places,
|
|
387
|
+
* and none for any other. An unknown receiver is left for the run to report.
|
|
388
|
+
*
|
|
389
|
+
* @throws Error when the place is missing, not this user's, or not the receiver's
|
|
390
|
+
*/
|
|
391
|
+
private checkTarget;
|
|
342
392
|
/**
|
|
343
393
|
* The request as the engine runs it: the receiver's default original when
|
|
344
394
|
* none was chosen, and a refusal for a choice the receiver does not offer
|
|
345
395
|
* (D11, #2021). An unknown receiver is left for the run to report.
|
|
346
396
|
*/
|
|
347
397
|
private withOriginal;
|
|
398
|
+
/**
|
|
399
|
+
* Vet one file before it is kept as a file (#2149): its type from its
|
|
400
|
+
* bytes (#1624), then its format's shim, when that shim is switched on,
|
|
401
|
+
* cleans it. FileManager asks this for every file it stores, and keeps the
|
|
402
|
+
* bytes returned, never the ones it sent; `removed` says what was taken
|
|
403
|
+
* out, for the uploader and the upload's record.
|
|
404
|
+
*
|
|
405
|
+
* Runs in the caller's request: cleaning is one linear pass over a file no
|
|
406
|
+
* larger than the site's upload limit. It decides nothing about permission:
|
|
407
|
+
* the caller has asked that first.
|
|
408
|
+
*
|
|
409
|
+
* @param ctx - Who is keeping the file (P1); only named in the log line when something was cleaned
|
|
410
|
+
* @throws IceVetRefused when the cleaning shim fails: the file could not be checked, so it is not kept
|
|
411
|
+
*/
|
|
412
|
+
vetFile(upload: IceUpload, ctx: ActorContext): Promise<IceVetResult>;
|
|
348
413
|
/**
|
|
349
414
|
* Run one import now and wait for it. For code already off the request
|
|
350
415
|
* path: an add-on's own background job, a test. A route uses
|
|
@@ -372,6 +437,11 @@ declare class ImportManager extends BaseManager {
|
|
|
372
437
|
* the store's sealed index entry written. Each is recorded in the ledger
|
|
373
438
|
* as the keep-once record (#2011), so the run reuses it and needs no key.
|
|
374
439
|
*
|
|
440
|
+
* A receiver whose `receive` itself may write into an encrypted store
|
|
441
|
+
* (`writesEncrypted`, #2118) has the whole run now, in this request, with
|
|
442
|
+
* `ctx` and its key, and the run's id is returned when it has ended: no
|
|
443
|
+
* key is ever carried into a job (#2034).
|
|
444
|
+
*
|
|
375
445
|
* @throws ImportUploadRefused when an original could not be kept; nothing is queued
|
|
376
446
|
*/
|
|
377
447
|
enqueueUpload(request: IceRunRequest, ctx: ActorContext): Promise<string>;
|
|
@@ -396,14 +466,105 @@ declare class ImportManager extends BaseManager {
|
|
|
396
466
|
/**
|
|
397
467
|
* Is an import into this receiver confidential (#2110)? Only when its
|
|
398
468
|
* destination is encrypted: a receiver that keeps into a sealed store
|
|
399
|
-
* (`keepsEncrypted`)
|
|
469
|
+
* (`keepsEncrypted`), or whose own door writes into one
|
|
470
|
+
* (`writesEncrypted`, #2118). No receiver can declare itself so otherwise. A
|
|
400
471
|
* confidential import's file names are shown to the uploader and kept in
|
|
401
|
-
* the audit log, and never written to application logs, notices
|
|
402
|
-
* screens; every other import logs them as before.
|
|
472
|
+
* the audit log, and never written to application logs, notices, admin
|
|
473
|
+
* screens or the import ledger (#2161); every other import logs them as before.
|
|
403
474
|
*/
|
|
404
475
|
isConfidential(receiverId: string): boolean;
|
|
405
476
|
/** Use this ledger instead of the file one: a test's, or a database table's. */
|
|
406
477
|
setImportLedger(ledger: IceLedger): void;
|
|
478
|
+
/**
|
|
479
|
+
* Register an export source (#2120): the owner's door for reading what is
|
|
480
|
+
* exported, checking its existing read permission (D5). Core's is
|
|
481
|
+
* `core.pages`.
|
|
482
|
+
*
|
|
483
|
+
* @returns The source's id, `<owner>.<name>`
|
|
484
|
+
* @throws Error when the source is malformed or its id is taken
|
|
485
|
+
*/
|
|
486
|
+
registerExportSource(owner: string, source: IceExportSource): string;
|
|
487
|
+
/**
|
|
488
|
+
* The formats the Export action offers this context for one thing (#2120):
|
|
489
|
+
* none when the source's owner would not let it export the thing (asked
|
|
490
|
+
* as an affordance, recording nothing), else each `out` shim, switched on,
|
|
491
|
+
* that can make a file from what the source yields.
|
|
492
|
+
*/
|
|
493
|
+
exportFormatsFor(sourceId: string, ref: string, ctx: ActorContext): Promise<IceExportFormat[]>;
|
|
494
|
+
/**
|
|
495
|
+
* Start an export (#2120), from the request that asked: the source reads
|
|
496
|
+
* the thing now, with the request's own context, so its owner's door
|
|
497
|
+
* decides with everything the request carries (step-up, a vault's key)
|
|
498
|
+
* and records the export. The shims run off the request path, in the ICE
|
|
499
|
+
* background job, as the user's own job context. Returns the run id at once.
|
|
500
|
+
*
|
|
501
|
+
* Before anything is read, the user may have at most
|
|
502
|
+
* `max-queued-per-user` exports queued or running, and a held run must be
|
|
503
|
+
* free to make room under `max-kept-runs`. Once read, the items count
|
|
504
|
+
* toward `max-held-bytes` until their file is made.
|
|
505
|
+
*
|
|
506
|
+
* @throws IceExportRefused when the thing is not there, the user may not
|
|
507
|
+
* export it, or the format is not one offered for it
|
|
508
|
+
* @throws IceExportNeedsFreshSignIn when the user holds the permission but
|
|
509
|
+
* step-up asks for a fresh sign-in
|
|
510
|
+
* @throws IceExportBusy when the user, or the site, is making as many
|
|
511
|
+
* exports as it may
|
|
512
|
+
* @throws IceExportFailed when the thing is larger than this site exports
|
|
513
|
+
*/
|
|
514
|
+
startExport(request: IceExportRequest, ctx: ActorContext): Promise<string>;
|
|
515
|
+
/** An export's status, to the user it runs as; null to anyone else, and once it is let go. */
|
|
516
|
+
getExportRun(runId: string, ctx: ActorContext): IceExportReport | null;
|
|
517
|
+
/** An export's file, to the user it runs as, while it is kept; null otherwise. */
|
|
518
|
+
exportFile(runId: string, ctx: ActorContext): {
|
|
519
|
+
name: string;
|
|
520
|
+
mediaType: string;
|
|
521
|
+
bytes: Buffer;
|
|
522
|
+
} | null;
|
|
523
|
+
/** The source's formats now: the enabled out shims' chains from what it yields. */
|
|
524
|
+
private exportChainsFor;
|
|
525
|
+
private executeExport;
|
|
526
|
+
/** The source's own record of how an export ended, if it keeps one; a record that fails is logged, never thrown. */
|
|
527
|
+
private recordExportOutcome;
|
|
528
|
+
/**
|
|
529
|
+
* Before a new export is read (#2120): refuse when the user already has
|
|
530
|
+
* `max-queued-per-user` exports queued or running, and let finished runs go
|
|
531
|
+
* until there is room under `max-kept-runs`. A queued or running run is
|
|
532
|
+
* never let go.
|
|
533
|
+
*
|
|
534
|
+
* @throws IceExportBusy when there is no room
|
|
535
|
+
*/
|
|
536
|
+
private makeRoomForExport;
|
|
537
|
+
/**
|
|
538
|
+
* Hold a new run with the bytes its items take until its file is made,
|
|
539
|
+
* which count toward `max-held-bytes` (#2120). Finished files are let go
|
|
540
|
+
* to make room, the user's own first ({@link finishedExportRuns}).
|
|
541
|
+
*
|
|
542
|
+
* @throws IceExportFailed when the items alone are more than it may hold
|
|
543
|
+
* @throws IceExportBusy when queued and running exports alone hold too much
|
|
544
|
+
*/
|
|
545
|
+
private holdExportRun;
|
|
546
|
+
/**
|
|
547
|
+
* Keep a made file in memory until `keep-minutes` have passed, never on
|
|
548
|
+
* disk: an export of a sealed vault's page must not rest unencrypted. Its
|
|
549
|
+
* items' bytes are released for the file's. Other finished files are let
|
|
550
|
+
* go when all would hold more than `ngdpbase.export.engine.max-held-bytes`,
|
|
551
|
+
* the user's own first.
|
|
552
|
+
*/
|
|
553
|
+
private keepExportFile;
|
|
554
|
+
/** Let finished files go, `username`'s own first, until all held bytes are at most `limit`. */
|
|
555
|
+
private letFilesGo;
|
|
556
|
+
/** Every byte exports hold: made files, and the items of runs not yet made. */
|
|
557
|
+
private heldExportBytes;
|
|
558
|
+
/**
|
|
559
|
+
* The runs that may be let go, in the order they are: done or failed only,
|
|
560
|
+
* `username`'s own oldest first, then everyone else's oldest first, so one
|
|
561
|
+
* user's exports push out their own before anyone else's (#2120).
|
|
562
|
+
*/
|
|
563
|
+
private finishedExportRuns;
|
|
564
|
+
private dropExportRun;
|
|
565
|
+
/** `ngdpbase.export.engine.*`: every limit an export applies is configuration (the chain's length is import's). */
|
|
566
|
+
private exportSettings;
|
|
567
|
+
private exportManager;
|
|
407
568
|
/**
|
|
408
569
|
* The ledger scope a run uses (#2013): bound to the receiver and to the user
|
|
409
570
|
* `ctx` names, by their identity `@id`; their username only when the
|
|
@@ -430,7 +591,7 @@ declare class ImportManager extends BaseManager {
|
|
|
430
591
|
private enabledShims;
|
|
431
592
|
/**
|
|
432
593
|
* Hand the queue to the background job. One job run drains every queued
|
|
433
|
-
* import, each under its own context. A job run that has finished draining
|
|
594
|
+
* import and export, each under its own context. A job run that has finished draining
|
|
434
595
|
* but is not yet marked done answers `enqueue` with its old run id; then
|
|
435
596
|
* try again shortly, so nothing queued is stranded.
|
|
436
597
|
*/
|
|
@@ -455,15 +616,101 @@ declare class ImportManager extends BaseManager {
|
|
|
455
616
|
* `core.pages` (D4): NCM into pages, through PageManager's save door, as the
|
|
456
617
|
* folder import saves. It checks `page-create` itself (D5). A title that
|
|
457
618
|
* already exists is a duplicate, as it is for the folder import by default.
|
|
619
|
+
* A title the user gave (#2130) replaces the one the file gives; when a
|
|
620
|
+
* page has it already, the item is refused, never saved over that page.
|
|
458
621
|
*/
|
|
459
622
|
private pagesReceiver;
|
|
460
623
|
/**
|
|
461
|
-
* `
|
|
462
|
-
*
|
|
463
|
-
*
|
|
464
|
-
*
|
|
624
|
+
* `page-export` for this page (#2120). For a page in a vault, asked about
|
|
625
|
+
* the page as the route door asks it (`hasPermissionOn`, #1539): the
|
|
626
|
+
* container rule, then the capability with the page's vault, so a
|
|
627
|
+
* site-wide role does not reach in. For any other page, the capability.
|
|
628
|
+
* An affordance asks whether it is held (no step-up); the door whether it
|
|
629
|
+
* is permitted, and a refusal to someone who holds it is step-up's.
|
|
630
|
+
*/
|
|
631
|
+
private mayExportPage;
|
|
632
|
+
/**
|
|
633
|
+
* `core.pages` as an export source (#2120, D5: pages export checks
|
|
634
|
+
* `page-export`). A page is offered for export when its reader may see it
|
|
635
|
+
* and holds `page-export` (affordances, recording nothing). Reading it
|
|
636
|
+
* for export asks `page-export` ({@link mayExportPage}), then reads through the page
|
|
637
|
+
* door (`readPage`), which decides `page-read` on the page and records a
|
|
638
|
+
* refusal. The export is recorded as `page-export`, with the format and
|
|
639
|
+
* the run, once the run has ended: a success only when the file was made.
|
|
640
|
+
*/
|
|
641
|
+
private pagesExportSource;
|
|
642
|
+
/**
|
|
643
|
+
* `core.files` (D4): a file into the public place through FileManager's
|
|
644
|
+
* write door, `put` (#2149), which asks `asset-upload` itself and vets the
|
|
645
|
+
* file. Also where a kept original goes (D11) when the chosen receiver does
|
|
646
|
+
* not keep its own. A name the user gave (#2130)
|
|
647
|
+
* is the stored file's name; when the shared pool has a file of that name
|
|
648
|
+
* already, the item is refused, never stored beside or over it.
|
|
465
649
|
*/
|
|
466
650
|
private filesReceiver;
|
|
651
|
+
/**
|
|
652
|
+
* `core.private-store` (#2118): a takeout (#1387) handed back into one of
|
|
653
|
+
* its owner's own private stores, read by the shim `core.takeout`. It
|
|
654
|
+
* replaces the takeout import's own door (#1472). Each page goes through
|
|
655
|
+
* PageManager's save door and each file through FileManager's write door
|
|
656
|
+
* (`put`), the doors an edit and an upload use, so a sealed store
|
|
657
|
+
* encrypts on write with no new crypto.
|
|
658
|
+
*
|
|
659
|
+
* - No new permission (D5): the rule the takeout import always had, the
|
|
660
|
+
* `account-security` permission and the user's own private container.
|
|
661
|
+
* - Its places (`targets`) are the user's own stores this context can
|
|
662
|
+
* write now: those on disk and the default one, an encrypted one only
|
|
663
|
+
* while it is unlocked in this session.
|
|
664
|
+
* - Its writes may be sealed (`writesEncrypted`): the engine runs an
|
|
665
|
+
* upload into it in the request, with the request's key, and an import
|
|
666
|
+
* into it is confidential (#2110): no file or page name is logged.
|
|
667
|
+
* - Importing the same takeout again leaves the store as the first import
|
|
668
|
+
* did (operator, 2026-09-25), except that a page or a file deleted since
|
|
669
|
+
* comes back (operator, 2026-10-30; #2171). The engine skips a file it
|
|
670
|
+
* already took (fingerprints), but a page with a uuid and a file are read
|
|
671
|
+
* again (`rechecks`): the uuid check below decides for a page, and for a
|
|
672
|
+
* file whether the store still holds its bytes (`ownStoreFingerprints`, read once a run),
|
|
673
|
+
* so one still held is `duplicate` and not put again (no second upload
|
|
674
|
+
* record). On a first import the file door returns a file the store
|
|
675
|
+
* already holds. A page whose uuid the store holds is `duplicate`: unchanged, or
|
|
676
|
+
* changed since the download, and then the page here is kept. A uuid
|
|
677
|
+
* used elsewhere on the site is `duplicate`, the page named only when
|
|
678
|
+
* the user may view it. A title held by a DIFFERENT page lands beside
|
|
679
|
+
* it as `Title (imported)`.
|
|
680
|
+
* - The original is the file itself: none is kept or cited (D11), as for `core.files`.
|
|
681
|
+
* - The run is recorded as one act, `store-import`, with counts only, and
|
|
682
|
+
* kept as a report page in the store, sealed when the store is (operator,
|
|
683
|
+
* 2026-09-25 and 2026-10-30): see {@link keepRunReport}.
|
|
684
|
+
*/
|
|
685
|
+
private privateStoreReceiver;
|
|
686
|
+
/** The takeout import's rule, unchanged (#1472): `account-security`, and only into the user's own container. */
|
|
687
|
+
private mayImportIntoOwnStore;
|
|
688
|
+
/** Where the private-store receiver writes, from configuration. */
|
|
689
|
+
private privateStoreSetup;
|
|
690
|
+
/**
|
|
691
|
+
* The user's own stores this context can write now (#2118): each store on
|
|
692
|
+
* disk and the default one, which a user on a new site has before they
|
|
693
|
+
* wrote anything; an encrypted one only while unlocked in this session.
|
|
694
|
+
* Making a store is its own door (#1414): an encrypted one needs keys.
|
|
695
|
+
*/
|
|
696
|
+
private ownStoresWritable;
|
|
697
|
+
/**
|
|
698
|
+
* One page or file of a takeout into the store `info.target` (#2118, as
|
|
699
|
+
* #1472 did). A file through FileManager's `put`; a page after the files
|
|
700
|
+
* it links to, its links pointed at their ids here, through PageManager's
|
|
701
|
+
* save door. Nothing here logs a page's or a file's name (#1461, #2110).
|
|
702
|
+
*/
|
|
703
|
+
private receiveTakeoutEntry;
|
|
704
|
+
/** A takeout's page into the store, as #1472 decided: see {@link privateStoreReceiver}. */
|
|
705
|
+
private saveTakeoutPage;
|
|
706
|
+
/**
|
|
707
|
+
* The run as one act (#1472's `store-import`): who, which store, and how
|
|
708
|
+
* each file went, as counts. Never a page's or a file's name (#1461); each
|
|
709
|
+
* file's own record is its door's (`asset-upload`, a sealed store's by id).
|
|
710
|
+
* The counts use the old door's keys, so whatever reads the event reads
|
|
711
|
+
* one shape.
|
|
712
|
+
*/
|
|
713
|
+
private recordStoreImport;
|
|
467
714
|
/**
|
|
468
715
|
* Get available format IDs
|
|
469
716
|
*
|
|
@@ -656,6 +903,22 @@ declare class ImportManager extends BaseManager {
|
|
|
656
903
|
/** The uploaded file's name, for the report page. */
|
|
657
904
|
sourceName?: string;
|
|
658
905
|
}): Promise<TakeoutImportReport>;
|
|
906
|
+
/**
|
|
907
|
+
* An engine run into `core.private-store` as the takeout report the old
|
|
908
|
+
* door keeps (code review of #2160, finding 3; operator, 2026-10-30), from
|
|
909
|
+
* the run's per-file status. Only a run that read a takeout keeps one.
|
|
910
|
+
* A file the run skipped as already imported is in neither count.
|
|
911
|
+
*
|
|
912
|
+
* @returns How many files no page links to
|
|
913
|
+
*/
|
|
914
|
+
private keepRunReport;
|
|
915
|
+
/**
|
|
916
|
+
* A takeout import's report, kept (operator, 2026-09-25): which files no
|
|
917
|
+
* page now in the store links to, counted in the log, and a page in the
|
|
918
|
+
* store it is about, sealed exactly when the store is, so it can name what
|
|
919
|
+
* a log may not. A failure to save it costs the record, never the import.
|
|
920
|
+
*/
|
|
921
|
+
private keepTakeoutReport;
|
|
659
922
|
/** The import report page's markdown. Private links are `[Title|store/Title]` (#1457). */
|
|
660
923
|
private takeoutReportMarkdown;
|
|
661
924
|
/**
|
|
@@ -105,6 +105,8 @@ declare class MediaManager extends BaseManager implements CatalogSource {
|
|
|
105
105
|
* what degraded means (#1155) — configured, wanted, not working.
|
|
106
106
|
*/
|
|
107
107
|
private recordFolderState;
|
|
108
|
+
/** One path per line, then "and N more" when the provider capped the list (#2191). */
|
|
109
|
+
private formatFileList;
|
|
108
110
|
/**
|
|
109
111
|
* Surface scan/rebuild anomalies to admins via /admin/notifications and the
|
|
110
112
|
* server log (#807). Missing folders, capture-date gaps, and processing
|
|
@@ -120,6 +120,12 @@ export interface PageSaveOptions {
|
|
|
120
120
|
from: string;
|
|
121
121
|
to: string;
|
|
122
122
|
} | null;
|
|
123
|
+
/**
|
|
124
|
+
* An import's file name, when the user gave the page another title
|
|
125
|
+
* (#2130): recorded on a `create` beside the title. Ignored for a private
|
|
126
|
+
* page, whose record names it by its vault name only.
|
|
127
|
+
*/
|
|
128
|
+
importedFrom?: string;
|
|
123
129
|
/**
|
|
124
130
|
* Suppress the event. For writes that are a side effect of an already
|
|
125
131
|
* audited operation, where a second record would describe the same act
|
|
@@ -908,6 +914,18 @@ declare class PageManager extends BaseManager implements CatalogSource {
|
|
|
908
914
|
* @throws PageAudienceRefusedError when the audience leaves `ctx` out
|
|
909
915
|
*/
|
|
910
916
|
private assertAudienceAdmits;
|
|
917
|
+
/**
|
|
918
|
+
* The write door's shared-folder check (#2125): a folder's page is added,
|
|
919
|
+
* changed, moved or deleted only by a context the PDP permits
|
|
920
|
+
* `shared-folder-file` on its folder, whatever route it came by (the
|
|
921
|
+
* editor, the raw editor, the API, a restore). Reading a folder
|
|
922
|
+
* (`shared-folder-read`, which every admin holds on every folder) opens
|
|
923
|
+
* its key, so the store would take the write: this is what refuses it.
|
|
924
|
+
* A name that is not a folder page is not checked here.
|
|
925
|
+
*
|
|
926
|
+
* @throws when `ctx` may not file into the page's folder
|
|
927
|
+
*/
|
|
928
|
+
private assertMayFileInSharedFolder;
|
|
911
929
|
/**
|
|
912
930
|
* Admin-override save (#689): the admin "Edit raw" textarea, split into
|
|
913
931
|
* frontmatter and body and written through the door (#1462).
|
|
@@ -1081,6 +1099,9 @@ declare class PageManager extends BaseManager implements CatalogSource {
|
|
|
1081
1099
|
* or a share link the owner issued that names this vault. Anyone else gets
|
|
1082
1100
|
* an empty list, the same as a vault with nothing in it. Whether each page
|
|
1083
1101
|
* may then be read is still the page door's answer.
|
|
1102
|
+
*
|
|
1103
|
+
* A shared folder (`SHARED_FOLDER_OWNER`, #2125): whoever the PDP permits
|
|
1104
|
+
* `shared-folder-read` on it.
|
|
1084
1105
|
*/
|
|
1085
1106
|
listVaultPages(ctx: ActorContext, owner: string, vault: string): Promise<Array<{
|
|
1086
1107
|
name: string;
|
|
@@ -1295,6 +1316,24 @@ declare class PageManager extends BaseManager implements CatalogSource {
|
|
|
1295
1316
|
owner: string;
|
|
1296
1317
|
store: string;
|
|
1297
1318
|
}>>;
|
|
1319
|
+
/**
|
|
1320
|
+
* The pages of shared folders that match (#2125), from each folder's own
|
|
1321
|
+
* sealed search index, as a private store's are found. Only the folders
|
|
1322
|
+
* `ctx` may read: each is asked `shared-folder-read` here, whatever the
|
|
1323
|
+
* caller passed, and a folder it may not read gives nothing, not even a
|
|
1324
|
+
* count (decision 7). Folder pages are in no site-wide index.
|
|
1325
|
+
*
|
|
1326
|
+
* @param ctx - Who is searching (#1179)
|
|
1327
|
+
* @param folders - The folders to search, by name (SharedFolderManager's list)
|
|
1328
|
+
* @param ask - The query, as {@link matchStoreSearch} reads it
|
|
1329
|
+
*/
|
|
1330
|
+
searchSharedFolderPages(ctx: ActorContext, folders: readonly string[], ask?: StoreSearchQuery): Promise<Array<StoreSearchMatch & {
|
|
1331
|
+
name: string;
|
|
1332
|
+
owner: string;
|
|
1333
|
+
store: string;
|
|
1334
|
+
}>>;
|
|
1335
|
+
/** Matches from `owner`'s `stores`' own search indexes, read through `ctx`; a store that will not read gives none. */
|
|
1336
|
+
private searchStoreIndexes;
|
|
1298
1337
|
/**
|
|
1299
1338
|
* Build a store's search index from its pages, replacing whatever is there.
|
|
1300
1339
|
*
|
|
@@ -1361,6 +1400,20 @@ declare class PageManager extends BaseManager implements CatalogSource {
|
|
|
1361
1400
|
* }
|
|
1362
1401
|
*/
|
|
1363
1402
|
pageExists(identifier: string, ctx: ActorContext): boolean;
|
|
1403
|
+
/**
|
|
1404
|
+
* The uuid of the page that holds `name` as its title, or as its slug (#2140).
|
|
1405
|
+
*
|
|
1406
|
+
* Whether a name is taken — the uniqueness question a save and the shipped
|
|
1407
|
+
* pages screen ask. An exact match, ignoring case, by the store's own rule
|
|
1408
|
+
* (the provider's `uuidHoldingName`); never the plural or fuzzy matching
|
|
1409
|
+
* `getPage` does for links, so "Reviews" is not held by "review".
|
|
1410
|
+
*
|
|
1411
|
+
* @param field - Which name: 'title' or 'slug'
|
|
1412
|
+
* @param name - The title or slug
|
|
1413
|
+
* @param ctx - Who is asking
|
|
1414
|
+
* @returns The holder's uuid, or null when no page holds it
|
|
1415
|
+
*/
|
|
1416
|
+
uuidHoldingName(field: 'title' | 'slug', name: string, ctx: ActorContext): string | null;
|
|
1364
1417
|
/**
|
|
1365
1418
|
* The private titles `ctx` can see in `owner`'s stores, by store id (#1457).
|
|
1366
1419
|
*
|
|
@@ -222,6 +222,10 @@ declare class SearchManager extends BaseManager {
|
|
|
222
222
|
* yields nothing rather than an error.
|
|
223
223
|
*
|
|
224
224
|
* A private row carries the page's private name, so `pageUrl` links to it.
|
|
225
|
+
*
|
|
226
|
+
* And the pages of the shared folders the requester may read (#2125), from
|
|
227
|
+
* each folder's own sealed index, through the same door. A folder they may
|
|
228
|
+
* not read gives nothing: no row, no title, no count (decision 7).
|
|
225
229
|
*/
|
|
226
230
|
private mergeOwnPrivateResults;
|
|
227
231
|
/**
|