diff --git a/src/backend/src/api/filesystem/FSNodeParam.js b/src/backend/src/api/filesystem/FSNodeParam.js
index a7ee048e5..50ce69374 100644
--- a/src/backend/src/api/filesystem/FSNodeParam.js
+++ b/src/backend/src/api/filesystem/FSNodeParam.js
@@ -32,7 +32,7 @@ module.exports = class FSNodeParam {
async consolidate ({ req, getParam }) {
const log = globalThis.services.get('log-service').create('fsnode-param');
- const fs = req.fs ?? Context.get('services').get('filesystem');
+ const fs = Context.get('services').get('filesystem');
let uidOrPath = getParam(this.srckey);
if ( uidOrPath === undefined ) {
diff --git a/src/backend/src/filesystem/FSAccessContext.js b/src/backend/src/filesystem/FSAccessContext.js
deleted file mode 100644
index 2b6773c5b..000000000
--- a/src/backend/src/filesystem/FSAccessContext.js
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (C) 2024 Puter Technologies Inc.
- *
- * This file is part of Puter.
- *
- * Puter is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published
- * by the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- */
-const FSNodeContext = require("./FSNodeContext");
-
-const { NodePathSelector, NodeUIDSelector, NodeInternalIDSelector } = require("./node/selectors");
-
-/**
- * Container for access implementations.
- *
- * Access implementations may vary depending on region,
- * user privileges, and other factors.
- *
- * @class FSAccessContext
- */
-module.exports = class FSAccessContext {
- constructor () {
- this.fsEntryFetcher = null;
- }
-
- /**
- * get_entry_by_path() returns a filesystem entry using
- * the path to the entry. Use this method when you need
- * to get a filesystem entry but don't need to collect
- * any other information about the entry.
- *
- * @warning The entry returned by this method is not
- * client-safe. Use FSNodeContext to get a client-safe
- * entry by calling it's fetchEntry() method.
- *
- * @param {*} path
- * @returns
- * @deprecated use get_entry({ path }) instead
- */
- async get_entry_by_path (path) {
- return await this.get_entry({ path });
- }
-
- /**
- * get_entry() returns a filesystem entry using
- * path, uid, or id associated with a filesystem
- * node. Use this method when you need to get a
- * filesystem entry but don't need to collect any
- * other information about the entry.
- *
- * @warning The entry returned by this method is not
- * client-safe. Use FSNodeContext to get a client-safe
- * entry by calling it's fetchEntry() method.
- *
- * @param {*} param0 options for getting the entry
- * @param {*} param0.path
- * @param {*} param0.uid
- * @param {*} param0.id please use mysql_id instead
- * @param {*} param0.mysql_id
- */
- async get_entry ({ path, uid, id, mysql_id, ...options }) {
- let fsNode = await this.node({ path, uid, id, mysql_id });
- await fsNode.fetchEntry(options);
- return fsNode.entry;
- }
-
- /**
- * node() returns a filesystem node using path, uid,
- * or id associated with a filesystem node. Use this
- * method when you need to get a filesystem node and
- * need to collect information about the entry.
- *
- * @param {*} location - path, uid, or id associated with a filesystem node
- * @returns
- */
- async node (selector) {
- if ( typeof selector === 'string' ) {
- if ( selector.startsWith('/') ) {
- selector = new NodePathSelector(selector);
- } else {
- selector = new NodeUIDSelector(selector);
- }
- }
-
- // TEMP: remove when these objects aren't used anymore
- if (
- typeof selector === 'object' &&
- selector.constructor.name === 'Object'
- ) {
- if ( selector.path ) {
- selector = new NodePathSelector(selector.path);
- } else if ( selector.uid ) {
- selector = new NodeUIDSelector(selector.uid);
- } else {
- selector = new NodeInternalIDSelector(
- 'mysql', selector.mysql_id);
- }
- }
-
- let fsNode = new FSNodeContext({
- services: this.services,
- selector,
- fs: this
- });
- return fsNode;
- }
-};
diff --git a/src/backend/src/filesystem/FilesystemService.js b/src/backend/src/filesystem/FilesystemService.js
index e6e2cdf44..03a2ad549 100644
--- a/src/backend/src/filesystem/FilesystemService.js
+++ b/src/backend/src/filesystem/FilesystemService.js
@@ -19,7 +19,6 @@
// TODO: database access can be a service
const { RESOURCE_STATUS_PENDING_CREATE } = require('../modules/puterfs/ResourceService.js');
const { TraceService } = require('../services/TraceService.js');
-const FSAccessContext = require('./FSAccessContext.js');
const PerformanceMonitor = require('../monitor/PerformanceMonitor.js');
const { NodePathSelector, NodeUIDSelector, NodeInternalIDSelector } = require('./node/selectors.js');
const FSNodeContext = require('./FSNodeContext.js');
@@ -158,22 +157,6 @@ class FilesystemService extends BaseService {
}));
}
- /**
- * @deprecated - temporary migration method
- */
- get_systemfs () {
- if ( ! this.systemfs_ ) {
- this.systemfs_ = new FSAccessContext();
- this.systemfs_.fsEntryFetcher = this.services.get('fsEntryFetcher');
- this.systemfs_.fsEntryService = this.services.get('fsEntryService');
- this.systemfs_.resourceService = this.services.get('resourceService');
- this.systemfs_.sizeService = this.services.get('sizeService');
- this.systemfs_.traceService = this.services.get('traceService');
- this.systemfs_.services = this.services;
- }
- return this.systemfs_;
- }
-
async mkshortcut ({ parent, name, user, target }) {
// Access Control
diff --git a/src/backend/src/filesystem/systemfs.js b/src/backend/src/filesystem/systemfs.js
deleted file mode 100644
index 4d2e5d56e..000000000
--- a/src/backend/src/filesystem/systemfs.js
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2024 Puter Technologies Inc.
- *
- * This file is part of Puter.
- *
- * Puter is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published
- * by the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- */
-const fs_ = require('fs');
-
-const FSAccessContext = require("./FSAccessContext");
-const DatabaseFSEntryFetcher = require("./storage/DatabaseFSEntryFetcher");
-const { DatabaseFSEntryService } = require('./storage/DatabaseFSEntryService.js');
-const { ResourceService } = require('./storage/ResourceService.js');
-const { SizeService } = require('./storage/SizeService.js');
-const config = require('../config.js');
-const { TraceService: FSTracer } = require('../services/TraceService.js');
-
-const systemfs = new FSAccessContext();
-
-systemfs.fsEntryFetcher = new DatabaseFSEntryFetcher();
-systemfs.fsEntryService = new DatabaseFSEntryService();
-systemfs.resourceService = new ResourceService();
-systemfs.sizeService = new SizeService();
-systemfs.traceService = new FSTracer();
-
-// Log usages every 10 seconds for debugging
-if ( config.usages_debug ) setInterval(async ()=>{
- await fs_.promises.writeFile('/tmp/user_usages.json', JSON.stringify(systemfs.sizeService.usages, null, 4));
-}, 10*1000);
-
-module.exports = systemfs;
diff --git a/src/backend/src/helpers.js b/src/backend/src/helpers.js
index 92fd19aeb..81749042c 100644
--- a/src/backend/src/helpers.js
+++ b/src/backend/src/helpers.js
@@ -30,12 +30,10 @@ const { Context } = require('./util/context');
const { NodeUIDSelector } = require('./filesystem/node/selectors');
const { stream_to_buffer } = require('./util/streamutil.js');
-let systemfs = null;
let services = null;
const tmp_provide_services = async ss => {
services = ss;
await services.ready;
- systemfs = services.get('filesystem').get_systemfs();
}
async function is_empty(dir_uuid){
diff --git a/src/backend/src/middleware/fs.js b/src/backend/src/middleware/fs.js
deleted file mode 100644
index 04971103d..000000000
--- a/src/backend/src/middleware/fs.js
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2024 Puter Technologies Inc.
- *
- * This file is part of Puter.
- *
- * Puter is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published
- * by the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- */
-const FSAccessContext = require('../filesystem/FSAccessContext.js');
-
-const fs = (req, res, next)=>{
- const systemfs = req.services.get('filesystem').get_systemfs();
- try {
- const fs = new FSAccessContext();
- fs.fsEntryFetcher = systemfs.fsEntryFetcher;
- fs.fsEntryService = systemfs.fsEntryService;
- fs.resourceService = systemfs.resourceService;
- fs.sizeService = systemfs.sizeService;
- fs.traceService = systemfs.traceService;
- fs.user = req.user;
- fs.services = req.services;
-
- // TODO: Decorate with AuthEntryFetcher
-
- req.fs = fs;
- } catch (e) {
- // TODO: log details about this error to another service
- console.error(e);
- return res.status(500).send({
- // TODO: standardize 500 errors to avoid inference attacks
- error: 'the operation could not be completed'
- });
- }
- next();
-}
-
-module.exports = fs;
diff --git a/src/backend/src/modules/web/lib/eggspress.js b/src/backend/src/modules/web/lib/eggspress.js
index 5cfb220fb..63c08e546 100644
--- a/src/backend/src/modules/web/lib/eggspress.js
+++ b/src/backend/src/modules/web/lib/eggspress.js
@@ -21,7 +21,6 @@ const multer = require('multer');
const multest = require('@heyputer/multest');
const api_error_handler = require('./api_error_handler.js');
-const fsBeforeMW = require('../../../middleware/fs.js');
const APIError = require('../../../api/APIError.js');
const { Context } = require('../../../util/context.js');
const { subdomain } = require('../../../helpers.js');
@@ -49,9 +48,6 @@ module.exports = function eggspress (route, settings, handler) {
if ( settings.abuse ) mw.push(require('../../../middleware/abuse')(settings.abuse));
if ( settings.auth ) mw.push(require('../../../middleware/auth'));
if ( settings.auth2 ) mw.push(require('../../../middleware/auth2'));
- if ( settings.fs ) {
- mw.push(fsBeforeMW);
- }
if ( settings.verified ) mw.push(require('../../../middleware/verified'));
if ( settings.json ) mw.push(express.json());
diff --git a/src/backend/src/routers/down.js b/src/backend/src/routers/down.js
index 78f13de3e..a0e5616e9 100644
--- a/src/backend/src/routers/down.js
+++ b/src/backend/src/routers/down.js
@@ -21,7 +21,6 @@ const express = require('express');
const router = express.Router();
const auth = require('../middleware/auth.js');
const config = require('../config.js');
-const fs = require('../middleware/fs.js');
const { DB_WRITE } = require('../services/database/consts.js');
const { NodePathSelector } = require('../filesystem/node/selectors.js');
const { HLRead } = require('../filesystem/hl_operations/hl_read.js');
@@ -30,7 +29,7 @@ const { UserActorType } = require('../services/auth/Actor.js');
// -----------------------------------------------------------------------//
// GET /down
// -----------------------------------------------------------------------//
-router.post('/down', auth, fs, express.json(), express.urlencoded({ extended: true }), async (req, res, next)=>{
+router.post('/down', auth, express.json(), express.urlencoded({ extended: true }), async (req, res, next)=>{
// check subdomain
const actor = req.actor;
@@ -70,7 +69,8 @@ router.post('/down', auth, fs, express.json(), express.urlencoded({ extended: tr
return res.status(400).send('Cannot download a directory.');
// resolve path to its FSEntry
- const fsnode = await req.fs.node(new NodePathSelector(path));
+ const svc_fs = req.services.get('filesystem');
+ const fsnode = await svc_fs.node(new NodePathSelector(path));
// not found
if( ! fsnode.exists() ) {
diff --git a/src/backend/src/routers/filesystem_api/batch/all.js b/src/backend/src/routers/filesystem_api/batch/all.js
index 700bea663..e0a8baf54 100644
--- a/src/backend/src/routers/filesystem_api/batch/all.js
+++ b/src/backend/src/routers/filesystem_api/batch/all.js
@@ -32,7 +32,6 @@ module.exports = eggspress('/batch', {
subdomain: 'api',
verified: true,
auth2: true,
- fs: true,
// json: true,
// files: ['file'],
// multest: true,
@@ -85,7 +84,8 @@ module.exports = eggspress('/batch', {
}
// Make sure usage is cached
- await req.fs.sizeService.get_usage(req.user.id);
+ const sizeService = x.get('services').get('sizeService');
+ await sizeService.get_usage(req.user.id);
globalThis.average_chunk_size = new MovingMode({
alpha: 0.7,
diff --git a/src/backend/src/routers/filesystem_api/delete.js b/src/backend/src/routers/filesystem_api/delete.js
index b77cbae71..1cda8244e 100644
--- a/src/backend/src/routers/filesystem_api/delete.js
+++ b/src/backend/src/routers/filesystem_api/delete.js
@@ -28,7 +28,6 @@ const FSNodeParam = require('../../api/filesystem/FSNodeParam.js');
module.exports = eggspress('/delete', {
subdomain: 'api',
auth2: true,
- fs: true,
json: true,
allowedMethods: ['POST'],
}, async (req, res, next) => {
@@ -52,7 +51,7 @@ module.exports = eggspress('/delete', {
// TODO: remove this pseudo-batch
for ( const item_path of paths ) {
const target = await (new FSNodeParam('path')).consolidate({
- req: { fs: req.fs, user },
+ req: { user },
getParam: () => item_path,
});
const hl_remove = new HLRemove();
diff --git a/src/backend/src/routers/suggest_apps.js b/src/backend/src/routers/suggest_apps.js
index 53c645f64..49c5cd1c7 100644
--- a/src/backend/src/routers/suggest_apps.js
+++ b/src/backend/src/routers/suggest_apps.js
@@ -22,7 +22,6 @@ const router = new express.Router();
const auth = require('../middleware/auth.js');
const config = require('../config');
const { Context } = require('../util/context.js');
-const fs = require('../middleware/fs.js');
const { NodeInternalIDSelector } = require('../filesystem/node/selectors.js');
// -----------------------------------------------------------------------//
diff --git a/src/backend/src/routers/whoami.js b/src/backend/src/routers/whoami.js
index 526df65e2..31bfde42c 100644
--- a/src/backend/src/routers/whoami.js
+++ b/src/backend/src/routers/whoami.js
@@ -29,7 +29,6 @@ const timeago = (() => {
const { get_taskbar_items, is_shared_with_anyone, suggest_app_for_fsentry, get_app, get_descendants, id2uuid } = require('../helpers');
const auth = require('../middleware/auth.js');
-const fs = require('../middleware/fs.js');
const _path = require('path');
const eggspress = require('../api/eggspress');
const { Context } = require('../util/context');
@@ -122,7 +121,7 @@ const WHOAMI_GET = eggspress('/whoami', {
// POST /whoami
// -----------------------------------------------------------------------//
const WHOAMI_POST = new express.Router();
-WHOAMI_POST.post('/whoami', auth, fs, express.json(), async (req, response, next)=>{
+WHOAMI_POST.post('/whoami', auth, express.json(), async (req, response, next)=>{
// check subdomain
if(require('../helpers').subdomain(req) !== 'api') {
return;
diff --git a/src/backend/src/routers/writeFile.js b/src/backend/src/routers/writeFile.js
index 44c4c4140..140e64ab5 100644
--- a/src/backend/src/routers/writeFile.js
+++ b/src/backend/src/routers/writeFile.js
@@ -37,7 +37,6 @@ const { HLRemove } = require('../filesystem/hl_operations/hl_remove');
// POST /writeFile
// -----------------------------------------------------------------------//
module.exports = eggspress('/writeFile', {
- fs: true,
files: ['file'],
allowedMethods: ['POST'],
}, async (req, res, next) => {
diff --git a/src/backend/src/routers/writeFile/mkdir.js b/src/backend/src/routers/writeFile/mkdir.js
index a6ac3cb25..b8d109360 100644
--- a/src/backend/src/routers/writeFile/mkdir.js
+++ b/src/backend/src/routers/writeFile/mkdir.js
@@ -20,7 +20,9 @@ module.exports = async function writeFile_handle_mkdir ({
user: actor.type.user,
actor,
});
+
+ const svc_fs = req.services.get('filesystem');
- const newdir_node = await req.fs.node(new NodeUIDSelector(r.uid));
+ const newdir_node = await svc_fs.node(new NodeUIDSelector(r.uid));
return res.send(await sign_file(await newdir_node.get('entry'), 'write'));
};
diff --git a/src/backend/src/routers/writeFile/write.js b/src/backend/src/routers/writeFile/write.js
index 0b90ae213..395a50fc4 100644
--- a/src/backend/src/routers/writeFile/write.js
+++ b/src/backend/src/routers/writeFile/write.js
@@ -25,7 +25,8 @@ module.exports = async function writeFile_handle_write ({
return res.status(500).send(e);
}
- const dirNode = await req.fs.node(new NodePathSelector(dirname));
+ const svc_fs = req.services.get('filesystem');
+ const dirNode = await svc_fs.node(new NodePathSelector(dirname));
// Upload files one by one
const returns = [];