@samanhappy/mcphub 0.10.6 → 0.11.1
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/README.fr.md +36 -152
- package/README.md +34 -255
- package/README.zh.md +33 -212
- package/dist/config/DaoConfigService.js +3 -3
- package/dist/config/DaoConfigService.js.map +1 -1
- package/dist/controllers/authController.js +2 -2
- package/dist/controllers/authController.js.map +1 -1
- package/dist/controllers/configController.js +32 -5
- package/dist/controllers/configController.js.map +1 -1
- package/dist/controllers/groupController.js +24 -24
- package/dist/controllers/groupController.js.map +1 -1
- package/dist/controllers/oauthClientController.js +13 -13
- package/dist/controllers/oauthClientController.js.map +1 -1
- package/dist/controllers/oauthDynamicRegistrationController.js +9 -9
- package/dist/controllers/oauthDynamicRegistrationController.js.map +1 -1
- package/dist/controllers/oauthServerController.js +1 -1
- package/dist/controllers/oauthServerController.js.map +1 -1
- package/dist/controllers/openApiController.js +1 -1
- package/dist/controllers/openApiController.js.map +1 -1
- package/dist/controllers/serverController.js +134 -96
- package/dist/controllers/serverController.js.map +1 -1
- package/dist/controllers/userController.js +22 -21
- package/dist/controllers/userController.js.map +1 -1
- package/dist/dao/DaoFactory.js +43 -0
- package/dist/dao/DaoFactory.js.map +1 -1
- package/dist/dao/DatabaseDaoFactory.js +86 -0
- package/dist/dao/DatabaseDaoFactory.js.map +1 -0
- package/dist/dao/GroupDaoDbImpl.js +131 -0
- package/dist/dao/GroupDaoDbImpl.js.map +1 -0
- package/dist/dao/OAuthClientDao.js +100 -0
- package/dist/dao/OAuthClientDao.js.map +1 -0
- package/dist/dao/OAuthClientDaoDbImpl.js +83 -0
- package/dist/dao/OAuthClientDaoDbImpl.js.map +1 -0
- package/dist/dao/OAuthTokenDao.js +161 -0
- package/dist/dao/OAuthTokenDao.js.map +1 -0
- package/dist/dao/OAuthTokenDaoDbImpl.js +92 -0
- package/dist/dao/OAuthTokenDaoDbImpl.js.map +1 -0
- package/dist/dao/ServerDaoDbImpl.js +109 -0
- package/dist/dao/ServerDaoDbImpl.js.map +1 -0
- package/dist/dao/SystemConfigDaoDbImpl.js +56 -0
- package/dist/dao/SystemConfigDaoDbImpl.js.map +1 -0
- package/dist/dao/UserConfigDaoDbImpl.js +61 -0
- package/dist/dao/UserConfigDaoDbImpl.js.map +1 -0
- package/dist/dao/UserDaoDbImpl.js +90 -0
- package/dist/dao/UserDaoDbImpl.js.map +1 -0
- package/dist/dao/index.js +11 -0
- package/dist/dao/index.js.map +1 -1
- package/dist/db/entities/Group.js +49 -0
- package/dist/db/entities/Group.js.map +1 -0
- package/dist/db/entities/OAuthClient.js +66 -0
- package/dist/db/entities/OAuthClient.js.map +1 -0
- package/dist/db/entities/OAuthToken.js +66 -0
- package/dist/db/entities/OAuthToken.js.map +1 -0
- package/dist/db/entities/Server.js +93 -0
- package/dist/db/entities/Server.js.map +1 -0
- package/dist/db/entities/SystemConfig.js +66 -0
- package/dist/db/entities/SystemConfig.js.map +1 -0
- package/dist/db/entities/User.js +45 -0
- package/dist/db/entities/User.js.map +1 -0
- package/dist/db/entities/UserConfig.js +45 -0
- package/dist/db/entities/UserConfig.js.map +1 -0
- package/dist/db/entities/index.js +18 -2
- package/dist/db/entities/index.js.map +1 -1
- package/dist/db/repositories/GroupRepository.js +81 -0
- package/dist/db/repositories/GroupRepository.js.map +1 -0
- package/dist/db/repositories/OAuthClientRepository.js +68 -0
- package/dist/db/repositories/OAuthClientRepository.js.map +1 -0
- package/dist/db/repositories/OAuthTokenRepository.js +159 -0
- package/dist/db/repositories/OAuthTokenRepository.js.map +1 -0
- package/dist/db/repositories/ServerRepository.js +80 -0
- package/dist/db/repositories/ServerRepository.js.map +1 -0
- package/dist/db/repositories/SystemConfigRepository.js +64 -0
- package/dist/db/repositories/SystemConfigRepository.js.map +1 -0
- package/dist/db/repositories/UserConfigRepository.js +69 -0
- package/dist/db/repositories/UserConfigRepository.js.map +1 -0
- package/dist/db/repositories/UserRepository.js +68 -0
- package/dist/db/repositories/UserRepository.js.map +1 -0
- package/dist/db/repositories/index.js +8 -1
- package/dist/db/repositories/index.js.map +1 -1
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -1
- package/dist/middlewares/auth.js +2 -2
- package/dist/middlewares/auth.js.map +1 -1
- package/dist/middlewares/userContext.js +1 -1
- package/dist/middlewares/userContext.js.map +1 -1
- package/dist/models/OAuth.js +90 -122
- package/dist/models/OAuth.js.map +1 -1
- package/dist/models/User.js +29 -48
- package/dist/models/User.js.map +1 -1
- package/dist/routes/index.js +2 -1
- package/dist/routes/index.js.map +1 -1
- package/dist/scripts/migrate-to-database.js +5 -0
- package/dist/scripts/migrate-to-database.js.map +1 -0
- package/dist/server.js +2 -2
- package/dist/server.js.map +1 -1
- package/dist/services/groupService.js +87 -113
- package/dist/services/groupService.js.map +1 -1
- package/dist/services/keepAliveService.js +58 -0
- package/dist/services/keepAliveService.js.map +1 -0
- package/dist/services/mcpOAuthProvider.js +22 -28
- package/dist/services/mcpOAuthProvider.js.map +1 -1
- package/dist/services/mcpService.js +73 -92
- package/dist/services/mcpService.js.map +1 -1
- package/dist/services/oauthServerService.js +26 -20
- package/dist/services/oauthServerService.js.map +1 -1
- package/dist/services/oauthService.js +11 -10
- package/dist/services/oauthService.js.map +1 -1
- package/dist/services/oauthSettingsStore.js +17 -12
- package/dist/services/oauthSettingsStore.js.map +1 -1
- package/dist/services/openApiGeneratorService.js +6 -7
- package/dist/services/openApiGeneratorService.js.map +1 -1
- package/dist/services/sseService.js +20 -62
- package/dist/services/sseService.js.map +1 -1
- package/dist/services/userService.js +38 -45
- package/dist/services/userService.js.map +1 -1
- package/dist/utils/migration.js +235 -0
- package/dist/utils/migration.js.map +1 -0
- package/dist/utils/oauthBearer.js +4 -4
- package/dist/utils/oauthBearer.js.map +1 -1
- package/frontend/dist/assets/index-BiA4eB7l.js +251 -0
- package/frontend/dist/assets/index-BiA4eB7l.js.map +1 -0
- package/frontend/dist/index.html +1 -1
- package/mcp_settings.json +23 -1
- package/package.json +1 -1
- package/frontend/dist/assets/index-DDht0WYq.js +0 -251
- package/frontend/dist/assets/index-DDht0WYq.js.map +0 -1
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { Group } from '../entities/Group.js';
|
|
2
|
+
import { getAppDataSource } from '../connection.js';
|
|
3
|
+
/**
|
|
4
|
+
* Repository for Group entity
|
|
5
|
+
*/
|
|
6
|
+
export class GroupRepository {
|
|
7
|
+
constructor() {
|
|
8
|
+
this.repository = getAppDataSource().getRepository(Group);
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Find all groups
|
|
12
|
+
*/
|
|
13
|
+
async findAll() {
|
|
14
|
+
return await this.repository.find({ order: { createdAt: 'ASC' } });
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Find group by ID
|
|
18
|
+
*/
|
|
19
|
+
async findById(id) {
|
|
20
|
+
return await this.repository.findOne({ where: { id } });
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Find group by name
|
|
24
|
+
*/
|
|
25
|
+
async findByName(name) {
|
|
26
|
+
return await this.repository.findOne({ where: { name } });
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Create a new group
|
|
30
|
+
*/
|
|
31
|
+
async create(group) {
|
|
32
|
+
const newGroup = this.repository.create(group);
|
|
33
|
+
return await this.repository.save(newGroup);
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Update an existing group
|
|
37
|
+
*/
|
|
38
|
+
async update(id, groupData) {
|
|
39
|
+
const group = await this.findById(id);
|
|
40
|
+
if (!group) {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
const updated = this.repository.merge(group, groupData);
|
|
44
|
+
return await this.repository.save(updated);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Delete a group
|
|
48
|
+
*/
|
|
49
|
+
async delete(id) {
|
|
50
|
+
const result = await this.repository.delete({ id });
|
|
51
|
+
return (result.affected ?? 0) > 0;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Check if group exists by ID
|
|
55
|
+
*/
|
|
56
|
+
async exists(id) {
|
|
57
|
+
const count = await this.repository.count({ where: { id } });
|
|
58
|
+
return count > 0;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Check if group exists by name
|
|
62
|
+
*/
|
|
63
|
+
async existsByName(name) {
|
|
64
|
+
const count = await this.repository.count({ where: { name } });
|
|
65
|
+
return count > 0;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Count total groups
|
|
69
|
+
*/
|
|
70
|
+
async count() {
|
|
71
|
+
return await this.repository.count();
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Find groups by owner
|
|
75
|
+
*/
|
|
76
|
+
async findByOwner(owner) {
|
|
77
|
+
return await this.repository.find({ where: { owner }, order: { createdAt: 'ASC' } });
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
export default GroupRepository;
|
|
81
|
+
//# sourceMappingURL=GroupRepository.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GroupRepository.js","sourceRoot":"","sources":["../../../src/db/repositories/GroupRepository.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEpD;;GAEG;AACH,MAAM,OAAO,eAAe;IAG1B;QACE,IAAI,CAAC,UAAU,GAAG,gBAAgB,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IAC5D,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,OAAO;QACX,OAAO,MAAM,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;IACrE,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,QAAQ,CAAC,EAAU;QACvB,OAAO,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;IAC1D,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,UAAU,CAAC,IAAY;QAC3B,OAAO,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;IAC5D,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,MAAM,CAAC,KAAoD;QAC/D,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC/C,OAAO,MAAM,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC9C,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,MAAM,CAAC,EAAU,EAAE,SAAyB;QAChD,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QACtC,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;QACxD,OAAO,MAAM,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC7C,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,MAAM,CAAC,EAAU;QACrB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;QACpD,OAAO,CAAC,MAAM,CAAC,QAAQ,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;IACpC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,MAAM,CAAC,EAAU;QACrB,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;QAC7D,OAAO,KAAK,GAAG,CAAC,CAAC;IACnB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,YAAY,CAAC,IAAY;QAC7B,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;QAC/D,OAAO,KAAK,GAAG,CAAC,CAAC;IACnB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,KAAK;QACT,OAAO,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;IACvC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,WAAW,CAAC,KAAa;QAC7B,OAAO,MAAM,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;IACvF,CAAC;CACF;AAED,eAAe,eAAe,CAAC"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { OAuthClient } from '../entities/OAuthClient.js';
|
|
2
|
+
import { getAppDataSource } from '../connection.js';
|
|
3
|
+
/**
|
|
4
|
+
* Repository for OAuthClient entity
|
|
5
|
+
*/
|
|
6
|
+
export class OAuthClientRepository {
|
|
7
|
+
constructor() {
|
|
8
|
+
this.repository = getAppDataSource().getRepository(OAuthClient);
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Find all OAuth clients
|
|
12
|
+
*/
|
|
13
|
+
async findAll() {
|
|
14
|
+
return await this.repository.find();
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Find OAuth client by client ID
|
|
18
|
+
*/
|
|
19
|
+
async findByClientId(clientId) {
|
|
20
|
+
return await this.repository.findOne({ where: { clientId } });
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Find OAuth clients by owner
|
|
24
|
+
*/
|
|
25
|
+
async findByOwner(owner) {
|
|
26
|
+
return await this.repository.find({ where: { owner } });
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Create a new OAuth client
|
|
30
|
+
*/
|
|
31
|
+
async create(client) {
|
|
32
|
+
const newClient = this.repository.create(client);
|
|
33
|
+
return await this.repository.save(newClient);
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Update an existing OAuth client
|
|
37
|
+
*/
|
|
38
|
+
async update(clientId, clientData) {
|
|
39
|
+
const client = await this.findByClientId(clientId);
|
|
40
|
+
if (!client) {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
const updated = this.repository.merge(client, clientData);
|
|
44
|
+
return await this.repository.save(updated);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Delete an OAuth client
|
|
48
|
+
*/
|
|
49
|
+
async delete(clientId) {
|
|
50
|
+
const result = await this.repository.delete({ clientId });
|
|
51
|
+
return (result.affected ?? 0) > 0;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Check if OAuth client exists
|
|
55
|
+
*/
|
|
56
|
+
async exists(clientId) {
|
|
57
|
+
const count = await this.repository.count({ where: { clientId } });
|
|
58
|
+
return count > 0;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Count total OAuth clients
|
|
62
|
+
*/
|
|
63
|
+
async count() {
|
|
64
|
+
return await this.repository.count();
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
export default OAuthClientRepository;
|
|
68
|
+
//# sourceMappingURL=OAuthClientRepository.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OAuthClientRepository.js","sourceRoot":"","sources":["../../../src/db/repositories/OAuthClientRepository.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEpD;;GAEG;AACH,MAAM,OAAO,qBAAqB;IAGhC;QACE,IAAI,CAAC,UAAU,GAAG,gBAAgB,EAAE,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC;IAClE,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,OAAO;QACX,OAAO,MAAM,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;IACtC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,cAAc,CAAC,QAAgB;QACnC,OAAO,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAC;IAChE,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,WAAW,CAAC,KAAa;QAC7B,OAAO,MAAM,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;IAC1D,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,MAAM,CAAC,MAA2D;QACtE,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACjD,OAAO,MAAM,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC/C,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,MAAM,CAAC,QAAgB,EAAE,UAAgC;QAC7D,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;QACnD,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;QAC1D,OAAO,MAAM,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC7C,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,MAAM,CAAC,QAAgB;QAC3B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC1D,OAAO,CAAC,MAAM,CAAC,QAAQ,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;IACpC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,MAAM,CAAC,QAAgB;QAC3B,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAC;QACnE,OAAO,KAAK,GAAG,CAAC,CAAC;IACnB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,KAAK;QACT,OAAO,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;IACvC,CAAC;CACF;AAED,eAAe,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { MoreThan } from 'typeorm';
|
|
2
|
+
import { OAuthToken } from '../entities/OAuthToken.js';
|
|
3
|
+
import { getAppDataSource } from '../connection.js';
|
|
4
|
+
/**
|
|
5
|
+
* Repository for OAuthToken entity
|
|
6
|
+
*/
|
|
7
|
+
export class OAuthTokenRepository {
|
|
8
|
+
constructor() {
|
|
9
|
+
this.repository = getAppDataSource().getRepository(OAuthToken);
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Find all OAuth tokens
|
|
13
|
+
*/
|
|
14
|
+
async findAll() {
|
|
15
|
+
return await this.repository.find();
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Find OAuth token by access token
|
|
19
|
+
*/
|
|
20
|
+
async findByAccessToken(accessToken) {
|
|
21
|
+
return await this.repository.findOne({ where: { accessToken } });
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Find OAuth token by refresh token
|
|
25
|
+
*/
|
|
26
|
+
async findByRefreshToken(refreshToken) {
|
|
27
|
+
return await this.repository.findOne({ where: { refreshToken } });
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Find OAuth tokens by client ID
|
|
31
|
+
*/
|
|
32
|
+
async findByClientId(clientId) {
|
|
33
|
+
return await this.repository.find({ where: { clientId } });
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Find OAuth tokens by username
|
|
37
|
+
*/
|
|
38
|
+
async findByUsername(username) {
|
|
39
|
+
return await this.repository.find({ where: { username } });
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Create a new OAuth token
|
|
43
|
+
*/
|
|
44
|
+
async create(token) {
|
|
45
|
+
// Remove any existing tokens with the same access token or refresh token
|
|
46
|
+
if (token.accessToken) {
|
|
47
|
+
await this.repository.delete({ accessToken: token.accessToken });
|
|
48
|
+
}
|
|
49
|
+
if (token.refreshToken) {
|
|
50
|
+
await this.repository.delete({ refreshToken: token.refreshToken });
|
|
51
|
+
}
|
|
52
|
+
const newToken = this.repository.create(token);
|
|
53
|
+
return await this.repository.save(newToken);
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Update an existing OAuth token
|
|
57
|
+
*/
|
|
58
|
+
async update(accessToken, tokenData) {
|
|
59
|
+
const token = await this.findByAccessToken(accessToken);
|
|
60
|
+
if (!token) {
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
const updated = this.repository.merge(token, tokenData);
|
|
64
|
+
return await this.repository.save(updated);
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Delete an OAuth token by access token
|
|
68
|
+
*/
|
|
69
|
+
async delete(accessToken) {
|
|
70
|
+
const result = await this.repository.delete({ accessToken });
|
|
71
|
+
return (result.affected ?? 0) > 0;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Check if OAuth token exists by access token
|
|
75
|
+
*/
|
|
76
|
+
async exists(accessToken) {
|
|
77
|
+
const count = await this.repository.count({ where: { accessToken } });
|
|
78
|
+
return count > 0;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Count total OAuth tokens
|
|
82
|
+
*/
|
|
83
|
+
async count() {
|
|
84
|
+
return await this.repository.count();
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Revoke token by access token or refresh token
|
|
88
|
+
*/
|
|
89
|
+
async revokeToken(token) {
|
|
90
|
+
// Try to find by access token first
|
|
91
|
+
let tokenEntity = await this.findByAccessToken(token);
|
|
92
|
+
if (!tokenEntity) {
|
|
93
|
+
// Try to find by refresh token
|
|
94
|
+
tokenEntity = await this.findByRefreshToken(token);
|
|
95
|
+
}
|
|
96
|
+
if (!tokenEntity) {
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
const result = await this.repository.delete({ id: tokenEntity.id });
|
|
100
|
+
return (result.affected ?? 0) > 0;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Revoke all tokens for a user
|
|
104
|
+
*/
|
|
105
|
+
async revokeUserTokens(username) {
|
|
106
|
+
const result = await this.repository.delete({ username });
|
|
107
|
+
return result.affected ?? 0;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Revoke all tokens for a client
|
|
111
|
+
*/
|
|
112
|
+
async revokeClientTokens(clientId) {
|
|
113
|
+
const result = await this.repository.delete({ clientId });
|
|
114
|
+
return result.affected ?? 0;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Clean up expired tokens
|
|
118
|
+
*/
|
|
119
|
+
async cleanupExpired() {
|
|
120
|
+
const now = new Date();
|
|
121
|
+
// Delete tokens where both access token and refresh token are expired
|
|
122
|
+
// (or refresh token doesn't exist)
|
|
123
|
+
const result = await this.repository
|
|
124
|
+
.createQueryBuilder()
|
|
125
|
+
.delete()
|
|
126
|
+
.from(OAuthToken)
|
|
127
|
+
.where('access_token_expires_at < :now', { now })
|
|
128
|
+
.andWhere('(refresh_token_expires_at IS NULL OR refresh_token_expires_at < :now)', { now })
|
|
129
|
+
.execute();
|
|
130
|
+
return result.affected ?? 0;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Check if access token is valid (exists and not expired)
|
|
134
|
+
*/
|
|
135
|
+
async isAccessTokenValid(accessToken) {
|
|
136
|
+
const count = await this.repository.count({
|
|
137
|
+
where: {
|
|
138
|
+
accessToken,
|
|
139
|
+
accessTokenExpiresAt: MoreThan(new Date()),
|
|
140
|
+
},
|
|
141
|
+
});
|
|
142
|
+
return count > 0;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Check if refresh token is valid (exists and not expired)
|
|
146
|
+
*/
|
|
147
|
+
async isRefreshTokenValid(refreshToken) {
|
|
148
|
+
const token = await this.findByRefreshToken(refreshToken);
|
|
149
|
+
if (!token) {
|
|
150
|
+
return false;
|
|
151
|
+
}
|
|
152
|
+
if (!token.refreshTokenExpiresAt) {
|
|
153
|
+
return true; // No expiration means always valid
|
|
154
|
+
}
|
|
155
|
+
return token.refreshTokenExpiresAt > new Date();
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
export default OAuthTokenRepository;
|
|
159
|
+
//# sourceMappingURL=OAuthTokenRepository.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OAuthTokenRepository.js","sourceRoot":"","sources":["../../../src/db/repositories/OAuthTokenRepository.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { Server } from '../entities/Server.js';
|
|
2
|
+
import { getAppDataSource } from '../connection.js';
|
|
3
|
+
/**
|
|
4
|
+
* Repository for Server entity
|
|
5
|
+
*/
|
|
6
|
+
export class ServerRepository {
|
|
7
|
+
constructor() {
|
|
8
|
+
this.repository = getAppDataSource().getRepository(Server);
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Find all servers
|
|
12
|
+
*/
|
|
13
|
+
async findAll() {
|
|
14
|
+
return await this.repository.find({ order: { createdAt: 'ASC' } });
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Find server by name
|
|
18
|
+
*/
|
|
19
|
+
async findByName(name) {
|
|
20
|
+
return await this.repository.findOne({ where: { name } });
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Create a new server
|
|
24
|
+
*/
|
|
25
|
+
async create(server) {
|
|
26
|
+
const newServer = this.repository.create(server);
|
|
27
|
+
return await this.repository.save(newServer);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Update an existing server
|
|
31
|
+
*/
|
|
32
|
+
async update(name, serverData) {
|
|
33
|
+
const server = await this.findByName(name);
|
|
34
|
+
if (!server) {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
const updated = this.repository.merge(server, serverData);
|
|
38
|
+
return await this.repository.save(updated);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Delete a server
|
|
42
|
+
*/
|
|
43
|
+
async delete(name) {
|
|
44
|
+
const result = await this.repository.delete({ name });
|
|
45
|
+
return (result.affected ?? 0) > 0;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Check if server exists
|
|
49
|
+
*/
|
|
50
|
+
async exists(name) {
|
|
51
|
+
const count = await this.repository.count({ where: { name } });
|
|
52
|
+
return count > 0;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Count total servers
|
|
56
|
+
*/
|
|
57
|
+
async count() {
|
|
58
|
+
return await this.repository.count();
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Find servers by owner
|
|
62
|
+
*/
|
|
63
|
+
async findByOwner(owner) {
|
|
64
|
+
return await this.repository.find({ where: { owner }, order: { createdAt: 'ASC' } });
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Find enabled servers
|
|
68
|
+
*/
|
|
69
|
+
async findEnabled() {
|
|
70
|
+
return await this.repository.find({ where: { enabled: true }, order: { createdAt: 'ASC' } });
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Set server enabled status
|
|
74
|
+
*/
|
|
75
|
+
async setEnabled(name, enabled) {
|
|
76
|
+
return await this.update(name, { enabled });
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
export default ServerRepository;
|
|
80
|
+
//# sourceMappingURL=ServerRepository.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ServerRepository.js","sourceRoot":"","sources":["../../../src/db/repositories/ServerRepository.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAC/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEpD;;GAEG;AACH,MAAM,OAAO,gBAAgB;IAG3B;QACE,IAAI,CAAC,UAAU,GAAG,gBAAgB,EAAE,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;IAC7D,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,OAAO;QACX,OAAO,MAAM,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;IACrE,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,UAAU,CAAC,IAAY;QAC3B,OAAO,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;IAC5D,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,MAAM,CAAC,MAAsD;QACjE,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACjD,OAAO,MAAM,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC/C,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,MAAM,CAAC,IAAY,EAAE,UAA2B;QACpD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QAC3C,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;QAC1D,OAAO,MAAM,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC7C,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,MAAM,CAAC,IAAY;QACvB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;QACtD,OAAO,CAAC,MAAM,CAAC,QAAQ,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;IACpC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,MAAM,CAAC,IAAY;QACvB,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;QAC/D,OAAO,KAAK,GAAG,CAAC,CAAC;IACnB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,KAAK;QACT,OAAO,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;IACvC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,WAAW,CAAC,KAAa;QAC7B,OAAO,MAAM,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;IACvF,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,WAAW;QACf,OAAO,MAAM,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;IAC/F,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,UAAU,CAAC,IAAY,EAAE,OAAgB;QAC7C,OAAO,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;IAC9C,CAAC;CACF;AAED,eAAe,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { SystemConfig } from '../entities/SystemConfig.js';
|
|
2
|
+
import { getAppDataSource } from '../connection.js';
|
|
3
|
+
/**
|
|
4
|
+
* Repository for SystemConfig entity
|
|
5
|
+
* Uses singleton pattern with id = 'default'
|
|
6
|
+
*/
|
|
7
|
+
export class SystemConfigRepository {
|
|
8
|
+
constructor() {
|
|
9
|
+
this.DEFAULT_ID = 'default';
|
|
10
|
+
this.repository = getAppDataSource().getRepository(SystemConfig);
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Get system configuration (singleton)
|
|
14
|
+
*/
|
|
15
|
+
async get() {
|
|
16
|
+
let config = await this.repository.findOne({ where: { id: this.DEFAULT_ID } });
|
|
17
|
+
// Create default if doesn't exist
|
|
18
|
+
if (!config) {
|
|
19
|
+
config = this.repository.create({
|
|
20
|
+
id: this.DEFAULT_ID,
|
|
21
|
+
routing: {},
|
|
22
|
+
install: {},
|
|
23
|
+
smartRouting: {},
|
|
24
|
+
mcpRouter: {},
|
|
25
|
+
nameSeparator: '-',
|
|
26
|
+
oauth: {},
|
|
27
|
+
oauthServer: {},
|
|
28
|
+
enableSessionRebuild: false,
|
|
29
|
+
});
|
|
30
|
+
config = await this.repository.save(config);
|
|
31
|
+
}
|
|
32
|
+
return config;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Update system configuration
|
|
36
|
+
*/
|
|
37
|
+
async update(configData) {
|
|
38
|
+
const config = await this.get();
|
|
39
|
+
const updated = this.repository.merge(config, configData);
|
|
40
|
+
return await this.repository.save(updated);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Reset system configuration to defaults
|
|
44
|
+
*/
|
|
45
|
+
async reset() {
|
|
46
|
+
await this.repository.delete({ id: this.DEFAULT_ID });
|
|
47
|
+
return await this.get();
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Get a specific configuration section
|
|
51
|
+
*/
|
|
52
|
+
async getSection(section) {
|
|
53
|
+
const config = await this.get();
|
|
54
|
+
return config[section];
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Update a specific configuration section
|
|
58
|
+
*/
|
|
59
|
+
async updateSection(section, value) {
|
|
60
|
+
return await this.update({ [section]: value });
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
export default SystemConfigRepository;
|
|
64
|
+
//# sourceMappingURL=SystemConfigRepository.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SystemConfigRepository.js","sourceRoot":"","sources":["../../../src/db/repositories/SystemConfigRepository.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEpD;;;GAGG;AACH,MAAM,OAAO,sBAAsB;IAIjC;QAFiB,eAAU,GAAG,SAAS,CAAC;QAGtC,IAAI,CAAC,UAAU,GAAG,gBAAgB,EAAE,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC;IACnE,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,GAAG;QACP,IAAI,MAAM,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;QAE/E,kCAAkC;QAClC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC;gBAC9B,EAAE,EAAE,IAAI,CAAC,UAAU;gBACnB,OAAO,EAAE,EAAE;gBACX,OAAO,EAAE,EAAE;gBACX,YAAY,EAAE,EAAE;gBAChB,SAAS,EAAE,EAAE;gBACb,aAAa,EAAE,GAAG;gBAClB,KAAK,EAAE,EAAE;gBACT,WAAW,EAAE,EAAE;gBACf,oBAAoB,EAAE,KAAK;aAC5B,CAAC,CAAC;YACH,MAAM,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC9C,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,MAAM,CAAC,UAAiC;QAC5C,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,EAAE,CAAC;QAChC,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;QAC1D,OAAO,MAAM,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC7C,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,KAAK;QACT,MAAM,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;QACtD,OAAO,MAAM,IAAI,CAAC,GAAG,EAAE,CAAC;IAC1B,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,UAAU,CAA+B,OAAU;QACvD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,EAAE,CAAC;QAChC,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC;IACzB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,aAAa,CACjB,OAAU,EACV,KAAsB;QAEtB,OAAO,MAAM,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,KAAK,EAA2B,CAAC,CAAC;IAC1E,CAAC;CACF;AAED,eAAe,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { UserConfig } from '../entities/UserConfig.js';
|
|
2
|
+
import { getAppDataSource } from '../connection.js';
|
|
3
|
+
/**
|
|
4
|
+
* Repository for UserConfig entity
|
|
5
|
+
*/
|
|
6
|
+
export class UserConfigRepository {
|
|
7
|
+
constructor() {
|
|
8
|
+
this.repository = getAppDataSource().getRepository(UserConfig);
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Get all user configs
|
|
12
|
+
*/
|
|
13
|
+
async getAll() {
|
|
14
|
+
const configs = await this.repository.find();
|
|
15
|
+
const result = {};
|
|
16
|
+
for (const config of configs) {
|
|
17
|
+
result[config.username] = config;
|
|
18
|
+
}
|
|
19
|
+
return result;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Get user config by username
|
|
23
|
+
*/
|
|
24
|
+
async get(username) {
|
|
25
|
+
return await this.repository.findOne({ where: { username } });
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Update user config
|
|
29
|
+
*/
|
|
30
|
+
async update(username, configData) {
|
|
31
|
+
let config = await this.get(username);
|
|
32
|
+
if (!config) {
|
|
33
|
+
// Create new config if doesn't exist
|
|
34
|
+
config = this.repository.create({
|
|
35
|
+
username,
|
|
36
|
+
routing: {},
|
|
37
|
+
additionalConfig: {},
|
|
38
|
+
...configData,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
// Merge with existing config
|
|
43
|
+
config = this.repository.merge(config, configData);
|
|
44
|
+
}
|
|
45
|
+
return await this.repository.save(config);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Delete user config
|
|
49
|
+
*/
|
|
50
|
+
async delete(username) {
|
|
51
|
+
const result = await this.repository.delete({ username });
|
|
52
|
+
return (result.affected ?? 0) > 0;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Get a specific configuration section for a user
|
|
56
|
+
*/
|
|
57
|
+
async getSection(username, section) {
|
|
58
|
+
const config = await this.get(username);
|
|
59
|
+
return config ? config[section] : null;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Update a specific configuration section for a user
|
|
63
|
+
*/
|
|
64
|
+
async updateSection(username, section, value) {
|
|
65
|
+
return await this.update(username, { [section]: value });
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
export default UserConfigRepository;
|
|
69
|
+
//# sourceMappingURL=UserConfigRepository.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"UserConfigRepository.js","sourceRoot":"","sources":["../../../src/db/repositories/UserConfigRepository.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEpD;;GAEG;AACH,MAAM,OAAO,oBAAoB;IAG/B;QACE,IAAI,CAAC,UAAU,GAAG,gBAAgB,EAAE,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;IACjE,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,MAAM;QACV,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;QAC7C,MAAM,MAAM,GAA+B,EAAE,CAAC;QAC9C,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC7B,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,MAAM,CAAC;QACnC,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,GAAG,CAAC,QAAgB;QACxB,OAAO,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAC;IAChE,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,MAAM,CAAC,QAAgB,EAAE,UAA+B;QAC5D,IAAI,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAEtC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,qCAAqC;YACrC,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC;gBAC9B,QAAQ;gBACR,OAAO,EAAE,EAAE;gBACX,gBAAgB,EAAE,EAAE;gBACpB,GAAG,UAAU;aACd,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,6BAA6B;YAC7B,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;QACrD,CAAC;QAED,OAAO,MAAM,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC5C,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,MAAM,CAAC,QAAgB;QAC3B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC1D,OAAO,CAAC,MAAM,CAAC,QAAQ,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;IACpC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,UAAU,CAA6B,QAAgB,EAAE,OAAU;QACvE,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACxC,OAAO,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACzC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,aAAa,CACjB,QAAgB,EAChB,OAAU,EACV,KAAoB;QAEpB,OAAO,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,KAAK,EAAyB,CAAC,CAAC;IAClF,CAAC;CACF;AAED,eAAe,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { User } from '../entities/User.js';
|
|
2
|
+
import { getAppDataSource } from '../connection.js';
|
|
3
|
+
/**
|
|
4
|
+
* Repository for User entity
|
|
5
|
+
*/
|
|
6
|
+
export class UserRepository {
|
|
7
|
+
constructor() {
|
|
8
|
+
this.repository = getAppDataSource().getRepository(User);
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Find all users
|
|
12
|
+
*/
|
|
13
|
+
async findAll() {
|
|
14
|
+
return await this.repository.find({ order: { createdAt: 'ASC' } });
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Find user by username
|
|
18
|
+
*/
|
|
19
|
+
async findByUsername(username) {
|
|
20
|
+
return await this.repository.findOne({ where: { username } });
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Create a new user
|
|
24
|
+
*/
|
|
25
|
+
async create(user) {
|
|
26
|
+
const newUser = this.repository.create(user);
|
|
27
|
+
return await this.repository.save(newUser);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Update an existing user
|
|
31
|
+
*/
|
|
32
|
+
async update(username, userData) {
|
|
33
|
+
const user = await this.findByUsername(username);
|
|
34
|
+
if (!user) {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
const updated = this.repository.merge(user, userData);
|
|
38
|
+
return await this.repository.save(updated);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Delete a user
|
|
42
|
+
*/
|
|
43
|
+
async delete(username) {
|
|
44
|
+
const result = await this.repository.delete({ username });
|
|
45
|
+
return (result.affected ?? 0) > 0;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Check if user exists
|
|
49
|
+
*/
|
|
50
|
+
async exists(username) {
|
|
51
|
+
const count = await this.repository.count({ where: { username } });
|
|
52
|
+
return count > 0;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Count total users
|
|
56
|
+
*/
|
|
57
|
+
async count() {
|
|
58
|
+
return await this.repository.count();
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Find all admin users
|
|
62
|
+
*/
|
|
63
|
+
async findAdmins() {
|
|
64
|
+
return await this.repository.find({ where: { isAdmin: true }, order: { createdAt: 'ASC' } });
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
export default UserRepository;
|
|
68
|
+
//# sourceMappingURL=UserRepository.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"UserRepository.js","sourceRoot":"","sources":["../../../src/db/repositories/UserRepository.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEpD;;GAEG;AACH,MAAM,OAAO,cAAc;IAGzB;QACE,IAAI,CAAC,UAAU,GAAG,gBAAgB,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;IAC3D,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,OAAO;QACX,OAAO,MAAM,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;IACrE,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,cAAc,CAAC,QAAgB;QACnC,OAAO,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAC;IAChE,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,MAAM,CAAC,IAAkD;QAC7D,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC7C,OAAO,MAAM,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC7C,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,MAAM,CAAC,QAAgB,EAAE,QAAuB;QACpD,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;QACjD,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QACtD,OAAO,MAAM,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC7C,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,MAAM,CAAC,QAAgB;QAC3B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC1D,OAAO,CAAC,MAAM,CAAC,QAAQ,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;IACpC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,MAAM,CAAC,QAAgB;QAC3B,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAC;QACnE,OAAO,KAAK,GAAG,CAAC,CAAC;IACnB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,KAAK;QACT,OAAO,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;IACvC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,UAAU;QACd,OAAO,MAAM,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;IAC/F,CAAC;CACF;AAED,eAAe,cAAc,CAAC"}
|
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
import VectorEmbeddingRepository from './VectorEmbeddingRepository.js';
|
|
2
|
+
import { UserRepository } from './UserRepository.js';
|
|
3
|
+
import { ServerRepository } from './ServerRepository.js';
|
|
4
|
+
import { GroupRepository } from './GroupRepository.js';
|
|
5
|
+
import { SystemConfigRepository } from './SystemConfigRepository.js';
|
|
6
|
+
import { UserConfigRepository } from './UserConfigRepository.js';
|
|
7
|
+
import { OAuthClientRepository } from './OAuthClientRepository.js';
|
|
8
|
+
import { OAuthTokenRepository } from './OAuthTokenRepository.js';
|
|
2
9
|
// Export all repositories
|
|
3
|
-
export { VectorEmbeddingRepository };
|
|
10
|
+
export { VectorEmbeddingRepository, UserRepository, ServerRepository, GroupRepository, SystemConfigRepository, UserConfigRepository, OAuthClientRepository, OAuthTokenRepository, };
|
|
4
11
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/db/repositories/index.ts"],"names":[],"mappings":"AAAA,OAAO,yBAAyB,MAAM,gCAAgC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/db/repositories/index.ts"],"names":[],"mappings":"AAAA,OAAO,yBAAyB,MAAM,gCAAgC,CAAC;AACvE,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAEjE,0BAA0B;AAC1B,OAAO,EACL,yBAAyB,EACzB,cAAc,EACd,gBAAgB,EAChB,eAAe,EACf,sBAAsB,EACtB,oBAAoB,EACpB,qBAAqB,EACrB,oBAAoB,GACrB,CAAC"}
|