feat(12.2-04): add the fileupload field with deferred uploads on the form session key
- sessionKey.ts: one 32-byte base64url key per form mount, sent only in headers - api/files.ts: FileRoutes over the record and child file routes, XHR upload with progress, 401 refresh and retry - FileuploadField and FileCaptionModal per UI-SPEC section 3: dropzone, image grid, rows, per-item states, client pre-checks, reorder, protected previews - FormView provides FORM_SESSION, counts pending changes as dirty and sends X-Session-Key on create and update - fileupload lang keys in en and pl, admin-spa docs note, deferred smoke test, rebuilt dist
This commit is contained in:
28
admin/src/app/sessionKey.ts
Normal file
28
admin/src/app/sessionKey.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
// Form session keys (D-02). A record form makes one key when it mounts and a
|
||||
// relation child modal makes its own when it opens. Uploads, file removals,
|
||||
// deferred relation calls and the final save carry the key in a header, so
|
||||
// the server can hold the work against it and commit it with the save. A key
|
||||
// never appears in a URL: it would end up in logs and the browser history.
|
||||
|
||||
/** Header of the record form's key. */
|
||||
export const SESSION_HEADER = 'X-Session-Key'
|
||||
|
||||
/** Header of a relation child modal's own key. */
|
||||
export const CHILD_SESSION_HEADER = 'X-Child-Session-Key'
|
||||
|
||||
/** Random bytes per key: 256 bits, above D-02's 128-bit floor. */
|
||||
const KEY_BYTES = 32
|
||||
|
||||
/**
|
||||
* A new key: 32 bytes from crypto.getRandomValues encoded as unpadded
|
||||
* base64url, 43 characters of A-Z a-z 0-9 _ - (the server's key pattern).
|
||||
*/
|
||||
export function newSessionKey(): string {
|
||||
const bytes = new Uint8Array(KEY_BYTES)
|
||||
globalThis.crypto.getRandomValues(bytes)
|
||||
let binary = ''
|
||||
for (const byte of bytes) {
|
||||
binary += String.fromCharCode(byte)
|
||||
}
|
||||
return btoa(binary).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '')
|
||||
}
|
||||
Reference in New Issue
Block a user