mirror of
https://github.com/AeThex-Corporation/AeThex-OS.git
synced 2026-04-18 06:17:21 +00:00
modified: client/src/pages/os.tsx
modified: docs/ENTITLEMENTS_QUICKSTART.md
This commit is contained in:
parent
53fa49295a
commit
411c57e508
4 changed files with 164 additions and 1405 deletions
|
|
@ -136,6 +136,12 @@ Response:
|
|||
```
|
||||
|
||||
## Notes
|
||||
- All OS routes are protected by the capability guard and expect authenticated context where relevant.
|
||||
- All OS routes are always protected by the capability guard and expect authenticated context where relevant.
|
||||
- Use Supabase console to inspect tables and audit logs.
|
||||
- For production, plan issuer key rotation via `aethex_issuer_keys`; rotation endpoints can be added similarly.
|
||||
|
||||
### Bot Integration Env (for external bots)
|
||||
Add these to your bot repo (not the OS) so it can call the OS API:
|
||||
- AETHEX_API_BASE=`https://<your-os-host>`
|
||||
- AETHEX_ISSUER_ID=`<issuer_id from step 2>`
|
||||
- AETHEX_REALM=`foundation` (optional; foundation already has required capabilities)
|
||||
|
|
|
|||
1446
package-lock.json
generated
1446
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -88,6 +88,7 @@
|
|||
"express": "^4.21.2",
|
||||
"express-session": "^1.18.1",
|
||||
"framer-motion": "^12.23.24",
|
||||
"html2canvas": "^1.4.1",
|
||||
"input-otp": "^1.4.2",
|
||||
"lucide-react": "^0.545.0",
|
||||
"memorystore": "^1.6.7",
|
||||
|
|
|
|||
114
server/routes.ts
114
server/routes.ts
|
|
@ -1188,6 +1188,120 @@ export async function registerRoutes(
|
|||
}
|
||||
});
|
||||
|
||||
// Simple in-memory file storage (per-user, session-based)
|
||||
const fileStore = new Map<string, any[]>();
|
||||
|
||||
app.get("/api/files", requireAuth, async (req, res) => {
|
||||
try {
|
||||
const userId = req.session.userId;
|
||||
if (!userId) return res.status(401).json({ error: "Unauthorized" });
|
||||
|
||||
const files = fileStore.get(userId) || [];
|
||||
const { path } = req.query;
|
||||
|
||||
// Filter by path
|
||||
const filtered = path
|
||||
? files.filter(f => f.path.startsWith(`${path}/`) || f.path === path)
|
||||
: files.filter(f => f.path === '/');
|
||||
|
||||
res.json({ files: filtered });
|
||||
} catch (error) {
|
||||
console.error("File list error:", error);
|
||||
res.status(500).json({ error: "Failed to fetch files" });
|
||||
}
|
||||
});
|
||||
|
||||
app.post("/api/files", requireAuth, async (req, res) => {
|
||||
try {
|
||||
const userId = req.session.userId;
|
||||
if (!userId) return res.status(401).json({ error: "Unauthorized" });
|
||||
|
||||
const { name, type, path, content, language } = req.body;
|
||||
if (!name || !type || !path) {
|
||||
return res.status(400).json({ error: "Missing required fields" });
|
||||
}
|
||||
|
||||
const fileId = randomUUID();
|
||||
const newFile = {
|
||||
id: fileId,
|
||||
user_id: userId,
|
||||
name,
|
||||
type,
|
||||
path,
|
||||
content: content || '',
|
||||
language: language || null,
|
||||
size: content?.length || 0,
|
||||
mime_type: null,
|
||||
parent_id: null,
|
||||
created_at: new Date().toISOString(),
|
||||
updated_at: new Date().toISOString(),
|
||||
};
|
||||
|
||||
const files = fileStore.get(userId) || [];
|
||||
files.push(newFile);
|
||||
fileStore.set(userId, files);
|
||||
|
||||
res.json(newFile);
|
||||
} catch (error) {
|
||||
console.error("File creation error:", error);
|
||||
res.status(500).json({ error: "Failed to create file" });
|
||||
}
|
||||
});
|
||||
|
||||
app.patch("/api/files/:id", requireAuth, async (req, res) => {
|
||||
try {
|
||||
const userId = req.session.userId;
|
||||
if (!userId) return res.status(401).json({ error: "Unauthorized" });
|
||||
|
||||
const { id } = req.params;
|
||||
const { name, content } = req.body;
|
||||
|
||||
const files = fileStore.get(userId) || [];
|
||||
const file = files.find(f => f.id === id);
|
||||
|
||||
if (!file) {
|
||||
return res.status(404).json({ error: "File not found" });
|
||||
}
|
||||
|
||||
if (name) file.name = name;
|
||||
if (content !== undefined) file.content = content;
|
||||
file.updated_at = new Date().toISOString();
|
||||
|
||||
res.json(file);
|
||||
} catch (error) {
|
||||
console.error("File update error:", error);
|
||||
res.status(500).json({ error: "Failed to update file" });
|
||||
}
|
||||
});
|
||||
|
||||
app.delete("/api/files/:id", requireAuth, async (req, res) => {
|
||||
try {
|
||||
const userId = req.session.userId;
|
||||
if (!userId) return res.status(401).json({ error: "Unauthorized" });
|
||||
|
||||
const { id } = req.params;
|
||||
let files = fileStore.get(userId) || [];
|
||||
const fileToDelete = files.find(f => f.id === id);
|
||||
|
||||
if (!fileToDelete) {
|
||||
return res.status(404).json({ error: "File not found" });
|
||||
}
|
||||
|
||||
// If folder, delete all files inside
|
||||
if (fileToDelete.type === 'folder') {
|
||||
files = files.filter(f => !f.path.startsWith(fileToDelete.path + '/') && f.id !== id);
|
||||
} else {
|
||||
files = files.filter(f => f.id !== id);
|
||||
}
|
||||
|
||||
fileStore.set(userId, files);
|
||||
res.json({ id, deleted: true });
|
||||
} catch (error) {
|
||||
console.error("File delete error:", error);
|
||||
res.status(500).json({ error: "Failed to delete file" });
|
||||
}
|
||||
});
|
||||
|
||||
app.get("/api/os/issuers/:id", async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
|
|
|
|||
Loading…
Reference in a new issue