@fyresmith/hive-server 4.0.0 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/routes/managed.js DELETED
@@ -1,163 +0,0 @@
1
- import { Router } from 'express';
2
- import { expressMiddleware } from '../lib/auth.js';
3
- import {
4
- createInvite,
5
- describeManagedStatus,
6
- initManagedState,
7
- listInvites,
8
- loadManagedState,
9
- pairMember,
10
- removeMember,
11
- revokeInvite,
12
- } from '../lib/managedState.js';
13
-
14
- const router = Router();
15
-
16
- function getVaultPath() {
17
- const value = String(process.env.VAULT_PATH ?? '').trim();
18
- if (!value) throw new Error('VAULT_PATH env var is required');
19
- return value;
20
- }
21
-
22
- function getOwnerDiscordId() {
23
- return String(process.env.OWNER_DISCORD_ID ?? '').trim();
24
- }
25
-
26
- function assertOwner(req, res) {
27
- const ownerId = getOwnerDiscordId();
28
- if (!ownerId) {
29
- res.status(500).json({ ok: false, error: 'OWNER_DISCORD_ID is not configured' });
30
- return false;
31
- }
32
- if (req.user?.id !== ownerId) {
33
- res.status(403).json({ ok: false, error: 'Owner access required' });
34
- return false;
35
- }
36
- return true;
37
- }
38
-
39
- router.get('/status', expressMiddleware, async (req, res) => {
40
- try {
41
- const state = await loadManagedState(getVaultPath());
42
- let status = describeManagedStatus(state, req.user.id);
43
- if (!state) {
44
- const isOwner = req.user.id === getOwnerDiscordId();
45
- status = {
46
- ...status,
47
- role: isOwner ? 'owner' : 'none',
48
- isOwner,
49
- };
50
- }
51
- res.json({
52
- ok: true,
53
- ...status,
54
- user: { id: req.user.id, username: req.user.username },
55
- });
56
- } catch (err) {
57
- res.status(500).json({ ok: false, error: err instanceof Error ? err.message : String(err) });
58
- }
59
- });
60
-
61
- router.post('/init', expressMiddleware, async (req, res) => {
62
- if (!assertOwner(req, res)) return;
63
- try {
64
- const state = await initManagedState({
65
- vaultPath: getVaultPath(),
66
- ownerDiscordId: getOwnerDiscordId(),
67
- ownerUser: req.user,
68
- });
69
- res.json({
70
- ok: true,
71
- managedInitialized: true,
72
- vaultId: state.vaultId,
73
- ownerDiscordId: state.ownerDiscordId,
74
- memberCount: Object.keys(state.members ?? {}).length,
75
- });
76
- } catch (err) {
77
- res.status(400).json({ ok: false, error: err instanceof Error ? err.message : String(err) });
78
- }
79
- });
80
-
81
- router.post('/pair', expressMiddleware, async (req, res) => {
82
- const code = String(req.body?.code ?? '').trim();
83
- if (!code) {
84
- return res.status(400).json({ ok: false, error: 'Invite code is required' });
85
- }
86
-
87
- try {
88
- const result = await pairMember({
89
- vaultPath: getVaultPath(),
90
- code,
91
- user: req.user,
92
- });
93
-
94
- res.json({
95
- ok: true,
96
- paired: result.paired,
97
- reason: result.reason,
98
- vaultId: result.state.vaultId,
99
- memberCount: Object.keys(result.state.members ?? {}).length,
100
- });
101
- } catch (err) {
102
- res.status(400).json({ ok: false, error: err instanceof Error ? err.message : String(err) });
103
- }
104
- });
105
-
106
- router.post('/unpair', expressMiddleware, async (req, res) => {
107
- if (!assertOwner(req, res)) return;
108
- const discordId = String(req.body?.discordId ?? '').trim();
109
- if (!discordId) {
110
- return res.status(400).json({ ok: false, error: 'discordId is required' });
111
- }
112
- try {
113
- const result = await removeMember({ vaultPath: getVaultPath(), discordId });
114
- res.json({
115
- ok: true,
116
- removed: result.removed,
117
- discordId,
118
- memberCount: Object.keys(result.state.members ?? {}).length,
119
- });
120
- } catch (err) {
121
- res.status(400).json({ ok: false, error: err instanceof Error ? err.message : String(err) });
122
- }
123
- });
124
-
125
- router.post('/invite/create', expressMiddleware, async (req, res) => {
126
- if (!assertOwner(req, res)) return;
127
- try {
128
- const invite = await createInvite({
129
- vaultPath: getVaultPath(),
130
- ownerDiscordId: getOwnerDiscordId(),
131
- createdBy: req.user.id,
132
- });
133
- res.json({ ok: true, invite });
134
- } catch (err) {
135
- res.status(400).json({ ok: false, error: err instanceof Error ? err.message : String(err) });
136
- }
137
- });
138
-
139
- router.get('/invite/list', expressMiddleware, async (req, res) => {
140
- if (!assertOwner(req, res)) return;
141
- try {
142
- const invites = await listInvites(getVaultPath());
143
- res.json({ ok: true, invites });
144
- } catch (err) {
145
- res.status(400).json({ ok: false, error: err instanceof Error ? err.message : String(err) });
146
- }
147
- });
148
-
149
- router.post('/invite/revoke', expressMiddleware, async (req, res) => {
150
- if (!assertOwner(req, res)) return;
151
- const code = String(req.body?.code ?? '').trim();
152
- if (!code) {
153
- return res.status(400).json({ ok: false, error: 'code is required' });
154
- }
155
- try {
156
- const invite = await revokeInvite({ vaultPath: getVaultPath(), code });
157
- res.json({ ok: true, invite });
158
- } catch (err) {
159
- res.status(400).json({ ok: false, error: err instanceof Error ? err.message : String(err) });
160
- }
161
- });
162
-
163
- export default router;