Skip to content

Commit 059c070

Browse files
committed
feat: implement AccountUPDeviceController with CRUD operations and add related routes for managing UP devices
1 parent f615700 commit 059c070

File tree

3 files changed

+157
-20
lines changed

3 files changed

+157
-20
lines changed
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
import { Request, Response } from 'express';
2+
import Joi from 'joi';
3+
import { AccountUPDeviceService } from 'podverse-orm';
4+
import { handleGenericErrorResponse } from '@api/controllers/helpers/error';
5+
import { validateBodyObject } from '@api/lib/validation';
6+
import { ensureAuthenticated } from '@api/lib/auth';
7+
8+
const createAccountUPDeviceSchema = Joi.object({
9+
up_endpoint: Joi.string().uri().required(),
10+
up_auth_key: Joi.string().required().allow(null)
11+
});
12+
13+
const updateAccountUPDeviceSchema = Joi.object({
14+
up_endpoint: Joi.string().uri().required(),
15+
up_auth_key: Joi.string().required().allow(null)
16+
});
17+
18+
const deleteAccountUPDeviceSchema = Joi.object({
19+
up_endpoint: Joi.string().uri().required()
20+
});
21+
22+
const updateLocaleForAccountSchema = Joi.object({
23+
locale: Joi.string().required()
24+
});
25+
26+
export class AccountUPDeviceController {
27+
private static accountUPDeviceService = new AccountUPDeviceService();
28+
29+
static async create(req: Request, res: Response): Promise<void> {
30+
ensureAuthenticated(req, res, async () => {
31+
validateBodyObject(createAccountUPDeviceSchema, req, res, async () => {
32+
try {
33+
const jwtUser = req.user!;
34+
const { up_endpoint, up_auth_key } = req.body as {
35+
up_endpoint: string;
36+
up_auth_key: string | null;
37+
};
38+
const accountUPDevice = await AccountUPDeviceController
39+
.accountUPDeviceService.create(jwtUser.id, {
40+
up_endpoint,
41+
up_auth_key
42+
});
43+
res.json(accountUPDevice);
44+
} catch (error) {
45+
handleGenericErrorResponse(res, error);
46+
}
47+
});
48+
});
49+
}
50+
51+
static async update(req: Request, res: Response): Promise<void> {
52+
ensureAuthenticated(req, res, async () => {
53+
validateBodyObject(updateAccountUPDeviceSchema, req, res, async () => {
54+
try {
55+
const jwtUser = req.user!;
56+
const { up_endpoint, up_auth_key } = req.body as {
57+
up_endpoint: string;
58+
up_auth_key: string | null;
59+
};
60+
const accountUPDevice = await AccountUPDeviceController
61+
.accountUPDeviceService.update(jwtUser.id, {
62+
up_endpoint,
63+
up_auth_key
64+
});
65+
res.json(accountUPDevice);
66+
} catch (error) {
67+
handleGenericErrorResponse(res, error);
68+
}
69+
});
70+
});
71+
}
72+
73+
static async delete(req: Request, res: Response): Promise<void> {
74+
ensureAuthenticated(req, res, async () => {
75+
validateBodyObject(deleteAccountUPDeviceSchema, req, res, async () => {
76+
try {
77+
const jwtUser = req.user!;
78+
const { up_endpoint } = req.body as {
79+
up_endpoint: string;
80+
};
81+
await AccountUPDeviceController
82+
.accountUPDeviceService.delete(jwtUser.id, {
83+
up_endpoint
84+
});
85+
res.json({ message: 'UP device deleted successfully' });
86+
} catch (error) {
87+
handleGenericErrorResponse(res, error);
88+
}
89+
});
90+
});
91+
}
92+
93+
static async getAllForAccount(req: Request, res: Response): Promise<void> {
94+
ensureAuthenticated(req, res, async () => {
95+
try {
96+
const jwtUser = req.user!;
97+
const devices = await AccountUPDeviceController.accountUPDeviceService.getAllForAccount(jwtUser.id);
98+
res.json(devices);
99+
} catch (error) {
100+
handleGenericErrorResponse(res, error);
101+
}
102+
});
103+
}
104+
105+
static async updateLocaleForAccount(req: Request, res: Response): Promise<void> {
106+
ensureAuthenticated(req, res, async () => {
107+
validateBodyObject(updateLocaleForAccountSchema, req, res, async () => {
108+
try {
109+
const jwtUser = req.user!;
110+
const { locale } = req.body as { locale: string };
111+
await AccountUPDeviceController.accountUPDeviceService.updateLocaleForAccount(jwtUser.id, { locale });
112+
res.json({ message: 'Locale updated for account devices' });
113+
} catch (error) {
114+
handleGenericErrorResponse(res, error);
115+
}
116+
});
117+
});
118+
}
119+
120+
static async deleteAllForAccount(req: Request, res: Response): Promise<void> {
121+
ensureAuthenticated(req, res, async () => {
122+
try {
123+
const jwtUser = req.user!;
124+
await AccountUPDeviceController.accountUPDeviceService.deleteAllForAccount(jwtUser.id);
125+
res.json({ message: 'All UP devices deleted successfully' });
126+
} catch (error) {
127+
handleGenericErrorResponse(res, error);
128+
}
129+
});
130+
}
131+
}

src/controllers/queue/queueResource.ts

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -17,26 +17,24 @@ class QueueResourceController {
1717

1818
static async getAllByAccountAbridged(req: Request, res: Response): Promise<void> {
1919
ensureAuthenticated(req, res, async () => {
20-
verifyQueueOwnership()(req, res, async () => {
21-
const account = req.user!;
22-
23-
try {
24-
const queueResources = await QueueResourceController
25-
.queueResourceService
26-
.getAllByAccountAbridged(account.id);
27-
28-
const minimized = queueResources.map((row: DTOQueueResourceAbridgedResponseData) =>
29-
Object.fromEntries(
30-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
31-
Object.entries(row).filter(([_, v]) => v !== null && v !== false)
32-
)
33-
);
34-
35-
res.status(200).json(minimized);
36-
} catch (err) {
37-
handleGenericErrorResponse(res, err);
38-
}
39-
});
20+
const account = req.user!;
21+
22+
try {
23+
const queueResources = await QueueResourceController
24+
.queueResourceService
25+
.getAllByAccountAbridged(account.id);
26+
27+
const minimized = queueResources.map((row: DTOQueueResourceAbridgedResponseData) =>
28+
Object.fromEntries(
29+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
30+
Object.entries(row).filter(([_, v]) => v !== null && v !== false)
31+
)
32+
);
33+
34+
res.status(200).json(minimized);
35+
} catch (err) {
36+
handleGenericErrorResponse(res, err);
37+
}
4038
});
4139
}
4240

src/routes/account.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { AccountNotificationChannelController } from '@api/controllers/account/a
1010
import { AccountNotificationChannelTypeController } from '@api/controllers/account/accountNotificationChannelType';
1111
import { AccountFCMDeviceController } from '@api/controllers/account/accountFCMDevice';
1212
import { AccountWebPushDeviceController } from '@api/controllers/account/accountWebPushDevice';
13+
import { AccountUPDeviceController } from '@api/controllers/account/accountUPDevice';
1314
import { rateLimitEndpoint } from '@api/lib/rateLimiter';
1415

1516
const router = Router();
@@ -41,6 +42,13 @@ router.delete('/webpush-device/delete', asyncHandler(AccountWebPushDeviceControl
4142
router.get('/webpush-device/all-for-account', asyncHandler(AccountWebPushDeviceController.getAllForAccount));
4243
router.put('/webpush-device/update-locale', asyncHandler(AccountWebPushDeviceController.updateLocaleForAccount));
4344

45+
router.post('/up-device/create', asyncHandler(AccountUPDeviceController.create));
46+
router.put('/up-device/update', asyncHandler(AccountUPDeviceController.update));
47+
router.delete('/up-device/delete', asyncHandler(AccountUPDeviceController.delete));
48+
router.get('/up-device/all-for-account', asyncHandler(AccountUPDeviceController.getAllForAccount));
49+
router.put('/up-device/update-locale', asyncHandler(AccountUPDeviceController.updateLocaleForAccount));
50+
router.delete('/up-device/delete-all', asyncHandler(AccountUPDeviceController.deleteAllForAccount));
51+
4452
router.post('/follow/account', asyncHandler(AccountFollowingAccountController.followAccount));
4553
router.post('/unfollow/account', asyncHandler(AccountFollowingAccountController.unfollowAccount));
4654

0 commit comments

Comments
 (0)