streamby-core 0.25.7 → 0.25.8

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.
@@ -15,6 +15,8 @@ const project_1 = require("./routes/project");
15
15
  const export_1 = require("./routes/export");
16
16
  const credential_1 = require("./routes/credential");
17
17
  const apiConnection_1 = require("./routes/apiConnection");
18
+ const member_1 = require("./routes/member");
19
+ const user_1 = require("./routes/user");
18
20
  const auth_2 = require("../services/auth");
19
21
  const encryption_1 = require("../utils/encryption");
20
22
  function createStreamByRouter(config) {
@@ -42,5 +44,7 @@ function createStreamByRouter(config) {
42
44
  router.use((0, export_1.exportRouter)(config));
43
45
  router.use((0, credential_1.credentialRouter)(config));
44
46
  router.use((0, apiConnection_1.apiConnectionRouter)(config));
47
+ router.use((0, member_1.memberRouter)(config));
48
+ router.use((0, user_1.userRouter)(config));
45
49
  return router;
46
50
  }
@@ -0,0 +1,3 @@
1
+ import { Router } from 'express';
2
+ import { StreamByConfig } from '../../types';
3
+ export declare function memberRouter(config: StreamByConfig): Router;
@@ -0,0 +1,181 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.memberRouter = memberRouter;
4
+ const express_1 = require("express");
5
+ const manager_1 = require("../../models/manager");
6
+ const auth_1 = require("../../utils/auth");
7
+ const connectionManager_1 = require("../../adapters/database/connectionManager");
8
+ const sql_1 = require("../../adapters/database/sql");
9
+ const VALID_ROLES = ['viewer', 'editor', 'admin'];
10
+ function memberRouter(config) {
11
+ const router = (0, express_1.Router)();
12
+ const Project = (0, manager_1.getModel)('projects');
13
+ const getSqlConnection = () => {
14
+ const sqlDb = config.databases?.find(db => db.type === 'sql');
15
+ if (!sqlDb || !(0, connectionManager_1.getConnectedIds)().includes(sqlDb.id))
16
+ return null;
17
+ return (0, connectionManager_1.getConnection)(sqlDb.id).client;
18
+ };
19
+ router.get('/projects/:id/members', async (req, res) => {
20
+ try {
21
+ const auth = req.auth;
22
+ const projectId = req.params.id;
23
+ const project = await Project.findOne({ _id: projectId });
24
+ if (!project) {
25
+ return res.status(404).json({ message: 'Project not found' });
26
+ }
27
+ if (!(0, auth_1.isProjectMember)(project, auth.userId)) {
28
+ return res.status(403).json({ message: 'Unauthorized project access' });
29
+ }
30
+ const mainDb = config.databases?.find(db => db.main);
31
+ if (!mainDb) {
32
+ return res.status(500).json({ message: 'Main database not configured' });
33
+ }
34
+ const User = (0, manager_1.getModel)('users');
35
+ const membersWithUsernames = await Promise.all(project.members.map(async (member) => {
36
+ const user = await User.findOne({ _id: member.userId });
37
+ return {
38
+ userId: member.userId,
39
+ username: user ? user.username : 'Unknown',
40
+ role: member.role,
41
+ profilePic: user ? user.profilePic : '',
42
+ };
43
+ }));
44
+ res.json({ members: membersWithUsernames, message: 'Project members fetched successfully' });
45
+ }
46
+ catch (err) {
47
+ res.status(500).json({ message: 'Failed to fetch project members', details: err.message });
48
+ }
49
+ });
50
+ router.post('/projects/:id/members', async (req, res) => {
51
+ try {
52
+ const auth = req.auth;
53
+ if (auth.role !== 'admin') {
54
+ return res.status(403).json({ message: 'Only admins can invite members' });
55
+ }
56
+ const projectId = req.params.id;
57
+ const { userId, role } = req.body;
58
+ if (!userId || !role) {
59
+ return res.status(400).json({ message: 'userId and role are required' });
60
+ }
61
+ if (!VALID_ROLES.includes(role)) {
62
+ return res.status(400).json({ message: `role must be one of: ${VALID_ROLES.join(', ')}` });
63
+ }
64
+ const project = await Project.findOne({ _id: projectId });
65
+ if (!project) {
66
+ return res.status(404).json({ message: 'Project not found' });
67
+ }
68
+ if (!(0, auth_1.isProjectMember)(project, auth.userId)) {
69
+ return res.status(403).json({ message: 'Unauthorized project access' });
70
+ }
71
+ const alreadyMember = project.members?.some((m) => m.userId?.toString() === userId?.toString());
72
+ if (alreadyMember) {
73
+ return res.status(400).json({ message: 'User is already a member of this project' });
74
+ }
75
+ const User = (0, manager_1.getModel)('users');
76
+ const user = await User.findOne({ _id: userId });
77
+ if (!user) {
78
+ return res.status(404).json({ message: 'User not found' });
79
+ }
80
+ const newMember = { userId, username: user.username, role, archived: false };
81
+ if (project.dbType === 'sql') {
82
+ const connection = getSqlConnection();
83
+ if (!connection) {
84
+ return res.status(503).json({ message: 'SQL connection not available' });
85
+ }
86
+ await sql_1.sqlAdapter.create(connection, 'project_members', {
87
+ projectId,
88
+ userId,
89
+ role,
90
+ archived: false,
91
+ }, 'streamby');
92
+ }
93
+ else {
94
+ await Project.update({ _id: projectId }, { $push: { members: newMember } });
95
+ }
96
+ res.status(201).json({ member: newMember, message: 'Member invited successfully' });
97
+ }
98
+ catch (err) {
99
+ res.status(500).json({ message: 'Failed to invite member', details: err.message });
100
+ }
101
+ });
102
+ router.patch('/projects/:id/members/:userId', async (req, res) => {
103
+ try {
104
+ const auth = req.auth;
105
+ if (auth.role !== 'admin') {
106
+ return res.status(403).json({ message: 'Only admins can update member roles' });
107
+ }
108
+ const projectId = req.params.id;
109
+ const targetUserId = req.params.userId;
110
+ const { role } = req.body;
111
+ if (!role || !VALID_ROLES.includes(role)) {
112
+ return res.status(400).json({ message: `role must be one of: ${VALID_ROLES.join(', ')}` });
113
+ }
114
+ const project = await Project.findOne({ _id: projectId });
115
+ if (!project) {
116
+ return res.status(404).json({ message: 'Project not found' });
117
+ }
118
+ if (!(0, auth_1.isProjectMember)(project, auth.userId)) {
119
+ return res.status(403).json({ message: 'Unauthorized project access' });
120
+ }
121
+ const memberExists = project.members?.some((m) => m.userId?.toString() === targetUserId?.toString());
122
+ if (!memberExists) {
123
+ return res.status(404).json({ message: 'Member not found in project' });
124
+ }
125
+ if (project.dbType === 'sql') {
126
+ const connection = getSqlConnection();
127
+ if (!connection) {
128
+ return res.status(503).json({ message: 'SQL connection not available' });
129
+ }
130
+ await sql_1.sqlAdapter.update(connection, 'project_members', { projectId, userId: targetUserId }, { role }, 'streamby');
131
+ }
132
+ else {
133
+ const updatedMembers = project.members.map((m) => m.userId?.toString() === targetUserId?.toString() ? { ...m, role } : m);
134
+ await Project.update({ _id: projectId }, { members: updatedMembers });
135
+ }
136
+ res.status(200).json({ message: 'Member role updated successfully' });
137
+ }
138
+ catch (err) {
139
+ res.status(500).json({ message: 'Failed to update member role', details: err.message });
140
+ }
141
+ });
142
+ router.delete('/projects/:id/members/:userId', async (req, res) => {
143
+ try {
144
+ const auth = req.auth;
145
+ if (auth.role !== 'admin') {
146
+ return res.status(403).json({ message: 'Only admins can remove members' });
147
+ }
148
+ const projectId = req.params.id;
149
+ const targetUserId = req.params.userId;
150
+ if (targetUserId === auth.userId) {
151
+ return res.status(400).json({ message: 'Cannot remove yourself from the project' });
152
+ }
153
+ const project = await Project.findOne({ _id: projectId });
154
+ if (!project) {
155
+ return res.status(404).json({ message: 'Project not found' });
156
+ }
157
+ if (!(0, auth_1.isProjectMember)(project, auth.userId)) {
158
+ return res.status(403).json({ message: 'Unauthorized project access' });
159
+ }
160
+ const memberExists = project.members?.some((m) => m.userId?.toString() === targetUserId?.toString());
161
+ if (!memberExists) {
162
+ return res.status(404).json({ message: 'Member not found in project' });
163
+ }
164
+ if (project.dbType === 'sql') {
165
+ const connection = getSqlConnection();
166
+ if (!connection) {
167
+ return res.status(503).json({ message: 'SQL connection not available' });
168
+ }
169
+ await sql_1.sqlAdapter.delete(connection, 'project_members', { projectId, userId: targetUserId }, 'streamby');
170
+ }
171
+ else {
172
+ await Project.update({ _id: projectId }, { $pull: { members: { userId: targetUserId } } });
173
+ }
174
+ res.status(200).json({ message: 'Member removed successfully' });
175
+ }
176
+ catch (err) {
177
+ res.status(500).json({ message: 'Failed to remove member', details: err.message });
178
+ }
179
+ });
180
+ return router;
181
+ }
@@ -234,38 +234,6 @@ function projectRouter(config) {
234
234
  res.status(500).json({ message: 'Failed to unarchive project', details: err.message });
235
235
  }
236
236
  });
237
- router.get('/projects/:id/members', async (req, res) => {
238
- try {
239
- const auth = req.auth;
240
- const projectId = req.params.id;
241
- const project = await Project.findOne({ _id: projectId });
242
- if (!project) {
243
- return res.status(404).json({ message: 'Project not found' });
244
- }
245
- if (!(0, auth_1.isProjectMember)(project, auth.userId)) {
246
- return res.status(403).json({ message: 'Unauthorized project access' });
247
- }
248
- const mainDb = config.databases?.find(db => db.main);
249
- if (!mainDb) {
250
- return res.status(500).json({ message: 'Main database not configured' });
251
- }
252
- const userDbType = mainDb.type;
253
- const User = (0, manager_1.getModel)('users', userDbType);
254
- const membersWithUsernames = await Promise.all(project.members.map(async (member) => {
255
- const user = await User.findOne({ _id: member.userId });
256
- return {
257
- userId: member.userId,
258
- username: user ? user.username : 'Unknown',
259
- role: member.role,
260
- profilePic: user ? user.profilePic : ''
261
- };
262
- }));
263
- res.json({ members: membersWithUsernames, message: 'Project members fetched successfully' });
264
- }
265
- catch (err) {
266
- res.status(500).json({ message: 'Failed to fetch project members', details: err.message });
267
- }
268
- });
269
237
  router.post('/projects/:id/image', async (req, res) => {
270
238
  try {
271
239
  const auth = req.auth;
@@ -0,0 +1,3 @@
1
+ import { Router } from 'express';
2
+ import { StreamByConfig } from '../../types';
3
+ export declare function userRouter(config: StreamByConfig): Router;
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.userRouter = userRouter;
4
+ const express_1 = require("express");
5
+ const manager_1 = require("../../models/manager");
6
+ function userRouter(config) {
7
+ const router = (0, express_1.Router)();
8
+ const User = (0, manager_1.getModel)('users');
9
+ router.get('/users/search', async (req, res) => {
10
+ try {
11
+ const auth = req.auth;
12
+ const q = (req.query.q || '').trim();
13
+ if (!q) {
14
+ return res.status(400).json({ message: 'Query param q is required' });
15
+ }
16
+ const allUsers = await User.find({});
17
+ const lower = q.toLowerCase();
18
+ const users = allUsers
19
+ .filter((u) => u.username?.toLowerCase().includes(lower))
20
+ .slice(0, 20)
21
+ .map((u) => ({
22
+ id: u._id || u.id,
23
+ username: u.username,
24
+ profilePic: u.profilePic || '',
25
+ }));
26
+ res.json({ users });
27
+ }
28
+ catch (err) {
29
+ res.status(500).json({ message: 'Failed to search users', details: err.message });
30
+ }
31
+ });
32
+ return router;
33
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "streamby-core",
3
- "version": "0.25.7",
3
+ "version": "0.25.8",
4
4
  "description": "StreamBy middleware framework for media storage management",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",