mirror of
https://github.com/HeyPuter/puter.git
synced 2026-08-24 23:17:23 +00:00
fix: misc write issues with fs + openrouter refresh (#3125)
* feat: refresh openrouter models every 15 min * fix: if no extensions, skip build step * fix: misc write issues with fs
This commit is contained in:
Generated
-23
@@ -6270,29 +6270,6 @@
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-wasm32-wasi/node_modules/@emnapi/core": {
|
||||
"version": "1.9.2",
|
||||
"resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.9.2.tgz",
|
||||
"integrity": "sha512-UC+ZhH3XtczQYfOlu3lNEkdW/p4dsJ1r/bP7H8+rhao3TTTMO1ATq/4DdIi23XuGoFY+Cz0JmCbdVl0hz9jZcA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@emnapi/wasi-threads": "1.2.1",
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-wasm32-wasi/node_modules/@emnapi/runtime": {
|
||||
"version": "1.9.2",
|
||||
"resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.9.2.tgz",
|
||||
"integrity": "sha512-3U4+MIWHImeyu1wnmVygh5WlgfYDtyf0k8AbLhMFxOipihf6nrWC4syIm/SwEeec0mNSafiiNnMJwbza/Is6Lw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-win32-arm64-msvc": {
|
||||
"version": "1.0.0-rc.18",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-rc.18.tgz",
|
||||
|
||||
@@ -1054,6 +1054,18 @@ export class LegacyFSController extends PuterController {
|
||||
const operation =
|
||||
typeof query.operation === 'string' ? query.operation : 'write';
|
||||
|
||||
// A valid write signature authorises overwriting the file's bytes,
|
||||
// not structural changes. Restrict copy/move/mkdir/rename/delete/trash
|
||||
// to a caller authenticated as the owner — otherwise a recipient of a
|
||||
// write-share could relocate or destroy the source via this endpoint.
|
||||
if (operation !== 'write' && req.actor?.user?.id !== userId) {
|
||||
throw new HttpError(
|
||||
403,
|
||||
`'${operation}' via signed URL requires owner authentication`,
|
||||
{ legacyCode: 'forbidden' },
|
||||
);
|
||||
}
|
||||
|
||||
// `write` — multipart upload, streamed directly to the v2 write path.
|
||||
if (operation === 'write') {
|
||||
const body = asRecord(req.body);
|
||||
@@ -1087,8 +1099,19 @@ export class LegacyFSController extends PuterController {
|
||||
}
|
||||
|
||||
// Non-write operations: route to existing service methods and sign the result.
|
||||
// The signature alone authorises only byte writes to `targetEntry`. Structural
|
||||
// ops (mkdir/rename/copy/move/delete) require a caller actor with explicit
|
||||
// ACL on the affected paths — mirroring the unsigned counterparts above.
|
||||
const record = asRecord(req.body);
|
||||
const callerActor = this.#requireActor(req);
|
||||
if (operation === 'mkdir') {
|
||||
await assertAccess(
|
||||
this.services.acl,
|
||||
this.services.fs,
|
||||
callerActor,
|
||||
targetEntry.path,
|
||||
'write',
|
||||
);
|
||||
const folderName =
|
||||
typeof record.name === 'string'
|
||||
? record.name
|
||||
@@ -1110,12 +1133,26 @@ export class LegacyFSController extends PuterController {
|
||||
throw new HttpError(400, '`new_name` required', {
|
||||
legacyCode: 'bad_request',
|
||||
});
|
||||
await assertAccess(
|
||||
this.services.acl,
|
||||
this.services.fs,
|
||||
callerActor,
|
||||
targetEntry.path,
|
||||
'write',
|
||||
);
|
||||
const renamed = await this.services.fs.rename(targetEntry, newName);
|
||||
await this.#emitGuiEvent('outer.gui.item.updated', renamed);
|
||||
res.json({ ...signEntry(renamed, signingCfg), path: renamed.path });
|
||||
return;
|
||||
}
|
||||
if (operation === 'delete' || operation === 'trash') {
|
||||
await assertAccess(
|
||||
this.services.acl,
|
||||
this.services.fs,
|
||||
callerActor,
|
||||
targetEntry.path,
|
||||
'write',
|
||||
);
|
||||
// Treat trash == delete (recursive). Most clients just call delete
|
||||
// directly; if a trash folder becomes important we can revisit.
|
||||
await this.services.fs.remove(userId, {
|
||||
@@ -1139,6 +1176,20 @@ export class LegacyFSController extends PuterController {
|
||||
this.stores.fsEntry,
|
||||
destRef,
|
||||
);
|
||||
await assertAccess(
|
||||
this.services.acl,
|
||||
this.services.fs,
|
||||
callerActor,
|
||||
targetEntry.path,
|
||||
operation === 'copy' ? 'read' : 'write',
|
||||
);
|
||||
await assertAccess(
|
||||
this.services.acl,
|
||||
this.services.fs,
|
||||
callerActor,
|
||||
destinationParent.path,
|
||||
'write',
|
||||
);
|
||||
const method = operation === 'copy' ? 'copy' : 'move';
|
||||
const result = await this.services.fs[method](userId, {
|
||||
source: targetEntry,
|
||||
|
||||
@@ -230,7 +230,7 @@ export class OpenRouterProvider implements IChatProvider {
|
||||
});
|
||||
|
||||
models = resp.data.data;
|
||||
kv.set('openrouterChat:models', models);
|
||||
kv.set('openrouterChat:models', models, { EX: 15 * 60 }); // cache for 15 minutes
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
|
||||
@@ -96,7 +96,7 @@ export class TogetherAIProvider implements IChatProvider {
|
||||
},
|
||||
max_tokens: 1000,
|
||||
});
|
||||
kv.set(this.#kvKey, models, { EX: 5 * 60 });
|
||||
kv.set(this.#kvKey, models, { EX: 15 * 60 });
|
||||
return models;
|
||||
}
|
||||
|
||||
|
||||
@@ -125,4 +125,5 @@ export interface IChatProvider {
|
||||
list(): string[] | Promise<string[]>;
|
||||
getDefaultModel(): string;
|
||||
complete(arg: ICompleteArguments): Promise<IChatCompleteResult>;
|
||||
checkModeration(text: string): { flagged: boolean; categories: string[] };
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ module.exports = async (options = {}) => {
|
||||
const entries = [];
|
||||
|
||||
for ( const extensionsDir of extension_directories ) {
|
||||
// console.log(`Reading extensions from ${extensionsDir}`);
|
||||
if ( ! fs.existsSync(extensionsDir) ) continue;
|
||||
// Read and process extension entries from the extensions directory
|
||||
const readdir_entries = fs.readdirSync(extensionsDir, { withFileTypes: true });
|
||||
for ( const entry of readdir_entries ) {
|
||||
|
||||
Reference in New Issue
Block a user