mirror of
https://github.com/AeThex-Corporation/AeThex-OS.git
synced 2026-04-27 01:37: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
|
## 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.
|
- 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.
|
- 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": "^4.21.2",
|
||||||
"express-session": "^1.18.1",
|
"express-session": "^1.18.1",
|
||||||
"framer-motion": "^12.23.24",
|
"framer-motion": "^12.23.24",
|
||||||
|
"html2canvas": "^1.4.1",
|
||||||
"input-otp": "^1.4.2",
|
"input-otp": "^1.4.2",
|
||||||
"lucide-react": "^0.545.0",
|
"lucide-react": "^0.545.0",
|
||||||
"memorystore": "^1.6.7",
|
"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) => {
|
app.get("/api/os/issuers/:id", async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const { id } = req.params;
|
const { id } = req.params;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue