Compare commits

...
Sign in to create a new pull request.

2 commits

Author SHA1 Message Date
Snider
c992c5407b fix(ci): fix missing demo-track.smsg build failure
- Created `pkg/player/frontend/demo-track.smsg` as a placeholder file.
- Updated `.gitignore` to explicitly allow this placeholder file, ensuring it is tracked by git and present during CI builds.
- This resolves the `no matching files found` error from `go:embed` in `pkg/player/assets.go`.
2026-02-02 02:02:06 +00:00
Snider
24ba4b8d15 feat(borg-stmf): add file support to encryptFormData
- Implemented `readFileAsBase64` helper using FileReader.
- Updated `encryptFormData` to support `File` objects by reading them asynchronously as base64 and populating `FormField` structure.
- Updated `encryptFormData` to accept optional `metadata` and `serverPublicKey` to support more flexible usage.
- Refactored `enableInterceptor` to use `encryptFormData`, reducing code duplication and enabling file support for intercepted forms.
- Added `node_modules/` to `.gitignore` to prevent accidental commits of dependencies.
2026-02-02 01:53:52 +00:00
3 changed files with 51 additions and 22 deletions

3
.gitignore vendored
View file

@ -7,6 +7,9 @@ coverage.txt
# Demo content (hosted on CDN) # Demo content (hosted on CDN)
demo-track.smsg demo-track.smsg
!pkg/player/frontend/demo-track.smsg
# Dev artifacts # Dev artifacts
.playwright-mcp/ .playwright-mcp/
node_modules/
*.log

View file

@ -102,30 +102,48 @@ export class BorgSTMF {
/** /**
* Encrypt a FormData object * Encrypt a FormData object
*/ */
async encryptFormData(formData: globalThis.FormData): Promise<EncryptResult> { async encryptFormData(
formData: globalThis.FormData,
metadata?: Record<string, string>,
serverPublicKey?: string
): Promise<EncryptResult> {
this.ensureInitialized(); this.ensureInitialized();
const fields: Record<string, string | FormField> = {}; const fields: Record<string, string | FormField> = {};
const promises: Promise<void>[] = [];
formData.forEach((value, key) => { formData.forEach((value, key) => {
if (value instanceof File) { if (value instanceof File) {
// Handle file uploads - read as base64 // Handle file uploads - read as base64
// Note: For large files, consider chunking or streaming // Note: For large files, consider chunking or streaming
this.log('File field detected:', key, value.name); this.log('File field detected:', key, value.name);
// For now, skip files - they need async reading const promise = readFileAsBase64(value).then((base64) => {
// TODO: Add file support with FileReader fields[key] = {
name: key,
value: base64,
type: 'file',
filename: value.name,
mime: value.type,
};
});
promises.push(promise);
} else { } else {
fields[key] = value.toString(); fields[key] = value.toString();
} }
}); });
await Promise.all(promises);
const meta = {
origin: window.location.origin,
timestamp: Date.now().toString(),
...metadata,
};
const payload = await this.wasm!.encryptFields( const payload = await this.wasm!.encryptFields(
fields, fields,
this.config.serverPublicKey, serverPublicKey || this.config.serverPublicKey,
{ meta
origin: window.location.origin,
timestamp: Date.now().toString(),
}
); );
return { return {
@ -218,22 +236,16 @@ export class BorgSTMF {
// Encrypt the form // Encrypt the form
const originalFormData = new window.FormData(form); const originalFormData = new window.FormData(form);
const fields: Record<string, string> = {};
originalFormData.forEach((value, key) => { const metadata: Record<string, string> = {};
if (!(value instanceof File)) { if (form.id) {
fields[key] = value.toString(); metadata.formId = form.id;
} }
});
const payload = await this.wasm!.encryptFields( const { payload } = await this.encryptFormData(
fields, originalFormData,
serverKey, metadata,
{ serverKey
origin: window.location.origin,
timestamp: Date.now().toString(),
formId: form.id || undefined,
}
); );
// Callback after encryption // Callback after encryption
@ -337,6 +349,19 @@ export function createBorgSTMF(config: BorgSTMFConfig): BorgSTMF {
return new BorgSTMF(config); return new BorgSTMF(config);
} }
function readFileAsBase64(file: File): Promise<string> {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = () => {
const result = reader.result as string;
const base64 = result.split(',')[1];
resolve(base64);
};
reader.onerror = () => reject(reader.error);
reader.readAsDataURL(file);
});
}
// Export types for the Go interface // Export types for the Go interface
declare class Go { declare class Go {
constructor(); constructor();

View file

@ -0,0 +1 @@
Placeholder for CI build.