org-core-js 0.0.1 → 0.0.2
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/cjs/core/index.js +2 -1
- package/cjs/core/plugins/auth.js +193 -0
- package/cjs/core/plugins/ws.js +238 -0
- package/cjs/core/plugins.js +19 -0
- package/cjs/core/repositoryCore.js +3 -1
- package/cjs/core/serverCore.js +2 -2
- package/cjs/fileCore.js +1 -1
- package/esm/core/index.js +2 -1
- package/esm/core/plugins/auth.js +239 -0
- package/esm/core/plugins/ws.js +247 -0
- package/esm/core/plugins.js +4 -0
- package/esm/core/repositoryCore.js +1 -1
- package/esm/core/serverCore.js +4 -2
- package/esm/fileCore.js +1 -1
- package/package.json +5 -1
package/cjs/core/index.js
CHANGED
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _jsonwebtoken = _interopRequireDefault(require("jsonwebtoken"));
|
|
8
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
9
|
+
//jwt.verify(token,'shhhhh');
|
|
10
|
+
var _default = ({
|
|
11
|
+
lib
|
|
12
|
+
}) => ({
|
|
13
|
+
async tokenRSA(data, v) {
|
|
14
|
+
// const key = ((await lib("cryptojs").decrypt(process.env.JWT_SECRET_PRIVATE, process.env.JWT_SECRET)) || '').replaceAll("__n__", "\n")
|
|
15
|
+
const key = lib("cryptojs").decodeBase64(process.env.JWT_SECRET_PRIVATE);
|
|
16
|
+
return _jsonwebtoken.default.sign(data, key, {
|
|
17
|
+
algorithm: 'RS256',
|
|
18
|
+
expiresIn: v ? v : '24h'
|
|
19
|
+
});
|
|
20
|
+
},
|
|
21
|
+
async verifyRSA(token) {
|
|
22
|
+
// const key = ((await lib("cryptojs").decrypt(process.env.JWT_SECRET_PUBLIC, process.env.JWT_SECRET)) || '').replaceAll("__n__", "\n")
|
|
23
|
+
const key = lib("cryptojs").decodeBase64(process.env.JWT_SECRET_PUBLIC);
|
|
24
|
+
return _jsonwebtoken.default.verify(token, key);
|
|
25
|
+
},
|
|
26
|
+
auth_info(roles) {
|
|
27
|
+
return async (ctx, reply) => {
|
|
28
|
+
try {
|
|
29
|
+
const token = String(ctx?.headers?.get("authorization") || ctx?.request.headers?.get("authorization") || ' ').split(' ')[1] || String(ctx?.query?.token || '') || '';
|
|
30
|
+
const info = await this.verifyRSA(token);
|
|
31
|
+
ctx.user = info.user || info.info || info.data || info.code || info;
|
|
32
|
+
if (!ctx?.user) {
|
|
33
|
+
ctx.status_ = 401;
|
|
34
|
+
reply.code(401).send({
|
|
35
|
+
error: '401 Unauthorized'
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
if (roles.length == 0) {} else if (!roles.find(role => ctx.user.role == role)) {
|
|
39
|
+
ctx.status_ = 401;
|
|
40
|
+
reply.code(401).send({
|
|
41
|
+
error: '401 Unauthorized'
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
} catch (error) {
|
|
45
|
+
if (roles.length > 0) {
|
|
46
|
+
ctx.status_ = 401;
|
|
47
|
+
return reply.code(401).send({
|
|
48
|
+
error: '401 Unauthorized'
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
ctx.user = {};
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
},
|
|
55
|
+
auth(roles) {
|
|
56
|
+
return async (ctx, reply) => {
|
|
57
|
+
try {
|
|
58
|
+
const token = String(ctx?.headers?.get("authorization") || ctx?.request.headers?.get("authorization") || ' ').split(' ')[1] || String(ctx?.query?.token || '') || '';
|
|
59
|
+
const info = await this.verifyRSA(token);
|
|
60
|
+
ctx.user = info.user || info.info || info.data || info.code || info;
|
|
61
|
+
const userInfo = JSON.parse((await lib("redis").client.get("user::" + ctx.user.id)) || "{}");
|
|
62
|
+
ctx.user.teams = userInfo?.teams || [];
|
|
63
|
+
if (!ctx?.user) {
|
|
64
|
+
ctx.status_ = 401;
|
|
65
|
+
reply.code(401).send({
|
|
66
|
+
error: '401 Unauthorized'
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
if (roles.length == 0) {} else if (!roles.find(role => (ctx?.user?.teams || []).find(team => team.role == role))) {
|
|
70
|
+
ctx.status_ = 401;
|
|
71
|
+
reply.code(401).send({
|
|
72
|
+
error: '401 Unauthorized'
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
} catch (error) {
|
|
76
|
+
console.log(error);
|
|
77
|
+
if (roles.length > 0) {
|
|
78
|
+
ctx.status_ = 401;
|
|
79
|
+
return reply.code(401).send({
|
|
80
|
+
error: '401 Unauthorized'
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
ctx.user = {};
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
},
|
|
87
|
+
permission_invite(roles) {
|
|
88
|
+
return async (ctx, reply) => {
|
|
89
|
+
try {
|
|
90
|
+
const token = String(ctx?.headers?.get("authorization") || ctx?.request.headers?.get("authorization") || ' ').split(' ')[1] || String(ctx?.query?.token || '') || '';
|
|
91
|
+
const info = await this.verifyRSA(token);
|
|
92
|
+
ctx.user = info.user || info.info || info.data || info.code || info;
|
|
93
|
+
const userInfo = JSON.parse((await lib("redis").client.get("user::" + ctx.user.id)) || "{}");
|
|
94
|
+
ctx.user.teams = userInfo?.teams || [];
|
|
95
|
+
if (roles.length == 0) {
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
const {
|
|
99
|
+
data
|
|
100
|
+
} = ctx.body;
|
|
101
|
+
ctx.user.teams = ctx.user.teams.filter(team => data.teams.find(t => t.id == team.id && data.schoolId == team.schoolId));
|
|
102
|
+
ctx.body.data.teams == ctx.body.data.teams.filter(team => {
|
|
103
|
+
const t = ctx.user.teams.find(t => t.id == team.id && roles.find(r => r == t.role));
|
|
104
|
+
return !!t;
|
|
105
|
+
});
|
|
106
|
+
if (!ctx?.user) {
|
|
107
|
+
ctx.status_ = 401;
|
|
108
|
+
reply.code(401).send({
|
|
109
|
+
error: '401 Unauthorized'
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
if (!roles.find(role => (ctx?.user?.teams || []).find(team => team.role == role))) {
|
|
113
|
+
ctx.status_ = 401;
|
|
114
|
+
reply.code(401).send({
|
|
115
|
+
error: '401 Unauthorized'
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
} catch (error) {
|
|
119
|
+
console.log(error);
|
|
120
|
+
if (roles.length > 0) {
|
|
121
|
+
ctx.status_ = 401;
|
|
122
|
+
return reply.code(401).send({
|
|
123
|
+
error: '401 Unauthorized'
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
ctx.user = {};
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
},
|
|
130
|
+
auth1(roles) {
|
|
131
|
+
return async (request, reply) => {
|
|
132
|
+
try {
|
|
133
|
+
const token = String(request.headers['authorization']).split(' ')[1];
|
|
134
|
+
const info = await this.verifyRSA(token);
|
|
135
|
+
request.user = info.user || info.info || info.data || info.code || info;
|
|
136
|
+
if (!request?.user) {
|
|
137
|
+
reply.code(401).send({
|
|
138
|
+
error: '401 Unauthorized'
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
if (roles.length == 0) {} else if (!roles.find(role => request.user.role == role)) {
|
|
142
|
+
reply.code(401).send({
|
|
143
|
+
error: '401 Unauthorized'
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
} catch (error) {
|
|
147
|
+
reply.code(401).send({
|
|
148
|
+
error: '401 Unauthorized'
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
},
|
|
153
|
+
qrcode() {
|
|
154
|
+
return async (request, reply) => {
|
|
155
|
+
const infoStr = String(request.query['identifier'] || '');
|
|
156
|
+
const res = "U2FsdGVkX182xxWCbg9dZxlmmhdMcGGs2xzfdfAXv9FUr/odoyBb4T/yWBQip45iQg5NZmRrrUgRKI3JjL2o5c3rQmKhl7fkKDETT3pF9aorvAYTllBElYq7lUgczSpUhyxPtkpCbrOhgbvHuX8pwCeEnptiEL4CZgorj26jQUO17IlSk1AY2bjwlNgAQuKEgrfacJVcNyn9LtKHHHIQP5LYKxxB5P1oXNEc540n8tcu7+og5x/Pnb9pnm79ZKXH";
|
|
157
|
+
const decrypt = lib("cryptojs").decrypt(res);
|
|
158
|
+
console.log(infoStr, 'd', decrypt);
|
|
159
|
+
if (!decrypt) {
|
|
160
|
+
reply.code(401).send({
|
|
161
|
+
error: '401 Unauthorized'
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
request.user = JSON.parse(decrypt).identifier || {};
|
|
165
|
+
if (!request.user.code) {
|
|
166
|
+
reply.code(401).send({
|
|
167
|
+
error: '401 Unauthorized'
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
};
|
|
171
|
+
},
|
|
172
|
+
async forgot(info, e = 5 * 60 * 60 + "s", n = 6) {
|
|
173
|
+
const verificationCode = lib('generate').number(n);
|
|
174
|
+
return {
|
|
175
|
+
verificationCode,
|
|
176
|
+
verificationJwt: await this.tokenRSA({
|
|
177
|
+
code: {
|
|
178
|
+
verificationCode,
|
|
179
|
+
password: true,
|
|
180
|
+
...info,
|
|
181
|
+
userId: info.id
|
|
182
|
+
}
|
|
183
|
+
}, e)
|
|
184
|
+
};
|
|
185
|
+
},
|
|
186
|
+
async code(user, e = 5 * 60 * 60 + "s") {
|
|
187
|
+
return await this.tokenRSA({
|
|
188
|
+
user,
|
|
189
|
+
login: true
|
|
190
|
+
}, e);
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
exports.default = _default;
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = exports.adapterElysia = void 0;
|
|
7
|
+
// websocket-manager.js
|
|
8
|
+
/**
|
|
9
|
+
* Cria um gerenciador de WebSockets.
|
|
10
|
+
* Este gerenciador armazena a configuração das rotas WS (autenticação, conexão, etc.)
|
|
11
|
+
* e a sincroniza com um adaptador específico (como o do Elysia).
|
|
12
|
+
*
|
|
13
|
+
* @param {object} adapter - O adaptador que irá lidar com a implementação do WebSocket (ex: adapterElysia).
|
|
14
|
+
* @returns {object} - Um objeto com métodos para configurar e sincronizar as rotas WS.
|
|
15
|
+
*/
|
|
16
|
+
var _default = ({
|
|
17
|
+
adapter
|
|
18
|
+
}) => {
|
|
19
|
+
// Armazena a configuração de cada path de WebSocket.
|
|
20
|
+
// Estrutura: { "/path": { connections: {}, events: {}, rooms: {}, room_handlers: {}, auth_fn, connection_fn } }
|
|
21
|
+
const wsConfig = {};
|
|
22
|
+
return {
|
|
23
|
+
/**
|
|
24
|
+
* Sincroniza todas as configurações de rotas definidas com `of()` com o adaptador.
|
|
25
|
+
* Deve ser chamado após todas as rotas terem sido definidas.
|
|
26
|
+
*/
|
|
27
|
+
async sync() {
|
|
28
|
+
for (const [path, config] of Object.entries(wsConfig)) {
|
|
29
|
+
adapter.addWs(path, config);
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
/**
|
|
33
|
+
* Define uma nova rota de WebSocket.
|
|
34
|
+
* @param {string} path - O caminho da rota (ex: "/chat").
|
|
35
|
+
* @returns {object} - Um objeto com métodos para configurar a rota (auth, connection, to, broadcast).
|
|
36
|
+
*/
|
|
37
|
+
of(path = "/") {
|
|
38
|
+
if (!wsConfig[path]) {
|
|
39
|
+
wsConfig[path] = {
|
|
40
|
+
connections: {},
|
|
41
|
+
events: {},
|
|
42
|
+
rooms: {},
|
|
43
|
+
room_handlers: {}
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
const output = {
|
|
47
|
+
auth(fn) {
|
|
48
|
+
wsConfig[path].auth_fn = fn;
|
|
49
|
+
return output;
|
|
50
|
+
},
|
|
51
|
+
connection(fn) {
|
|
52
|
+
wsConfig[path].connection_fn = fn;
|
|
53
|
+
return output;
|
|
54
|
+
},
|
|
55
|
+
to(roomName) {
|
|
56
|
+
const roomInterface = {
|
|
57
|
+
on(eventName, fn) {
|
|
58
|
+
if (!wsConfig[path].room_handlers[roomName]) {
|
|
59
|
+
wsConfig[path].room_handlers[roomName] = {};
|
|
60
|
+
}
|
|
61
|
+
if (!wsConfig[path].room_handlers[roomName][eventName]) {
|
|
62
|
+
wsConfig[path].room_handlers[roomName][eventName] = new Map();
|
|
63
|
+
}
|
|
64
|
+
wsConfig[path].room_handlers[roomName][eventName].set(fn, fn);
|
|
65
|
+
return roomInterface;
|
|
66
|
+
},
|
|
67
|
+
off(eventName, fn) {
|
|
68
|
+
const handlers = wsConfig[path].room_handlers[roomName]?.[eventName];
|
|
69
|
+
if (handlers && handlers.has(fn)) {
|
|
70
|
+
handlers.delete(fn);
|
|
71
|
+
if (handlers.size === 0) {
|
|
72
|
+
delete wsConfig[path].room_handlers[roomName][eventName];
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return roomInterface;
|
|
76
|
+
},
|
|
77
|
+
emit(eventName, data) {
|
|
78
|
+
const members = wsConfig[path].rooms[roomName];
|
|
79
|
+
if (!members) return;
|
|
80
|
+
members.forEach(memberId => {
|
|
81
|
+
const targetSocket = wsConfig[path].connections[memberId];
|
|
82
|
+
if (targetSocket) {
|
|
83
|
+
targetSocket.emit(eventName, data);
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
return roomInterface;
|
|
89
|
+
},
|
|
90
|
+
/**
|
|
91
|
+
* NOVO: Envia um evento (broadcast) do servidor para TODOS os clientes conectados nesta rota.
|
|
92
|
+
* @param {string} eventName - O nome do evento a ser enviado.
|
|
93
|
+
* @param {any} data - Os dados do evento.
|
|
94
|
+
* @returns {object} - Retorna `output` para permitir encadeamento.
|
|
95
|
+
*/
|
|
96
|
+
emit(eventName, data) {
|
|
97
|
+
const allConnections = wsConfig[path].connections;
|
|
98
|
+
// Itera sobre todos os sockets conectados a este path
|
|
99
|
+
for (const socket of Object.values(allConnections)) {
|
|
100
|
+
// Usa o método emit do socket individual para garantir a formatação correta
|
|
101
|
+
socket.emit(eventName, data);
|
|
102
|
+
}
|
|
103
|
+
return output;
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
return output;
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
};
|
|
110
|
+
/**
|
|
111
|
+
* Adaptador para integrar o gerenciador de WebSockets com o framework Elysia.
|
|
112
|
+
* @param {object} server - A instância do servidor Elysia.
|
|
113
|
+
* @returns {object} - Um objeto com o método `addWs` para registrar as rotas.
|
|
114
|
+
*/
|
|
115
|
+
exports.default = _default;
|
|
116
|
+
const adapterElysia = server => {
|
|
117
|
+
return {
|
|
118
|
+
async addWs(path, config) {
|
|
119
|
+
server.ws(path, {
|
|
120
|
+
async open(ws) {
|
|
121
|
+
let isAuthenticated = true;
|
|
122
|
+
const socket = {
|
|
123
|
+
id: ws.id,
|
|
124
|
+
request: ws.data,
|
|
125
|
+
close: () => ws.close(),
|
|
126
|
+
rooms: new Set(),
|
|
127
|
+
_path: path,
|
|
128
|
+
send: obj => ws.send(JSON.stringify(obj)),
|
|
129
|
+
emit(eventName, data) {
|
|
130
|
+
this.send({
|
|
131
|
+
event: eventName,
|
|
132
|
+
data
|
|
133
|
+
});
|
|
134
|
+
},
|
|
135
|
+
on(eventName, fn) {
|
|
136
|
+
if (!config.events[ws.id]) {
|
|
137
|
+
config.events[ws.id] = {};
|
|
138
|
+
}
|
|
139
|
+
if (!config.events[ws.id][eventName]) {
|
|
140
|
+
config.events[ws.id][eventName] = [];
|
|
141
|
+
}
|
|
142
|
+
config.events[ws.id][eventName].push(fn);
|
|
143
|
+
},
|
|
144
|
+
join(roomName) {
|
|
145
|
+
if (!config.rooms[roomName]) {
|
|
146
|
+
config.rooms[roomName] = new Set();
|
|
147
|
+
}
|
|
148
|
+
config.rooms[roomName].add(this.id);
|
|
149
|
+
this.rooms.add(roomName);
|
|
150
|
+
},
|
|
151
|
+
leave(roomName) {
|
|
152
|
+
if (config.rooms[roomName]) {
|
|
153
|
+
config.rooms[roomName].delete(this.id);
|
|
154
|
+
if (config.rooms[roomName].size === 0) {
|
|
155
|
+
delete config.rooms[roomName];
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
this.rooms.delete(roomName);
|
|
159
|
+
},
|
|
160
|
+
to(roomName) {
|
|
161
|
+
return {
|
|
162
|
+
emit: (eventName, data) => {
|
|
163
|
+
const members = config.rooms[roomName];
|
|
164
|
+
if (!members) return;
|
|
165
|
+
members.forEach(memberId => {
|
|
166
|
+
if (memberId !== this.id) {
|
|
167
|
+
const targetSocket = config.connections[memberId];
|
|
168
|
+
if (targetSocket) {
|
|
169
|
+
targetSocket.emit(eventName, data);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
config.connections[ws.id] = socket;
|
|
178
|
+
config.events[ws.id] = {};
|
|
179
|
+
if (config.auth_fn) {
|
|
180
|
+
try {
|
|
181
|
+
await config.auth_fn(socket, error => {
|
|
182
|
+
if (error) {
|
|
183
|
+
ws.close();
|
|
184
|
+
isAuthenticated = false;
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
} catch (error) {
|
|
188
|
+
console.error("Erro durante a autenticação do WebSocket:", error);
|
|
189
|
+
ws.close();
|
|
190
|
+
isAuthenticated = false;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
if (!isAuthenticated) {
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
if (config.connection_fn) {
|
|
197
|
+
await config.connection_fn(socket);
|
|
198
|
+
}
|
|
199
|
+
},
|
|
200
|
+
async message(ws, message) {
|
|
201
|
+
try {
|
|
202
|
+
const event = message;
|
|
203
|
+
const senderSocket = config.connections[ws.id];
|
|
204
|
+
if (!senderSocket) return;
|
|
205
|
+
const connectionEvents = config.events[ws.id];
|
|
206
|
+
if (connectionEvents && connectionEvents[event.event]) {
|
|
207
|
+
connectionEvents[event.event].forEach(fn => fn(event.data));
|
|
208
|
+
}
|
|
209
|
+
for (const roomName of senderSocket.rooms) {
|
|
210
|
+
const roomHandlers = config.room_handlers[roomName]?.[event.event];
|
|
211
|
+
if (roomHandlers) {
|
|
212
|
+
roomHandlers.forEach(fn => {
|
|
213
|
+
fn(senderSocket, event.data);
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
} catch (error) {
|
|
218
|
+
console.error("Falha ao processar a mensagem do WebSocket:", error);
|
|
219
|
+
}
|
|
220
|
+
},
|
|
221
|
+
close(ws) {
|
|
222
|
+
const socket = config.connections[ws.id];
|
|
223
|
+
if (!socket) return;
|
|
224
|
+
const disconnectListeners = config.events[ws.id]?.disconnect;
|
|
225
|
+
if (disconnectListeners) {
|
|
226
|
+
disconnectListeners.forEach(fn => fn({
|
|
227
|
+
id: ws.id
|
|
228
|
+
}));
|
|
229
|
+
}
|
|
230
|
+
socket.rooms.forEach(roomName => socket.leave(roomName));
|
|
231
|
+
delete config.events[ws.id];
|
|
232
|
+
delete config.connections[ws.id];
|
|
233
|
+
}
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
};
|
|
237
|
+
};
|
|
238
|
+
exports.adapterElysia = adapterElysia;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
Object.defineProperty(exports, "adapterElysia", {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: function () {
|
|
9
|
+
return _ws.adapterElysia;
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
Object.defineProperty(exports, "ws", {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
get: function () {
|
|
15
|
+
return _ws.default;
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
var _ws = _interopRequireWildcard(require("./plugins/ws"));
|
|
19
|
+
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
package/cjs/core/serverCore.js
CHANGED
package/cjs/fileCore.js
CHANGED
|
@@ -23,5 +23,5 @@ var _default = exports.default = {
|
|
|
23
23
|
if (!this.exist(paths)) return [];
|
|
24
24
|
return _fs.default.readdirSync(_path.default.resolve(this.path + paths));
|
|
25
25
|
},
|
|
26
|
-
bin: _fs.default.existsSync(process.cwd() + '/esm') ? '/esm' : '/node_modules/
|
|
26
|
+
bin: _fs.default.existsSync(process.cwd() + '/esm') ? '/esm' : '/node_modules/org-core-js/esm'
|
|
27
27
|
};
|
package/esm/core/index.js
CHANGED
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
|
|
2
|
+
import jwt from 'jsonwebtoken';
|
|
3
|
+
//jwt.verify(token,'shhhhh');
|
|
4
|
+
export default ({ lib }) => ({
|
|
5
|
+
async tokenRSA(data, v) {
|
|
6
|
+
// const key = ((await lib("cryptojs").decrypt(process.env.JWT_SECRET_PRIVATE, process.env.JWT_SECRET)) || '').replaceAll("__n__", "\n")
|
|
7
|
+
const key= lib("cryptojs").decodeBase64(process.env.JWT_SECRET_PRIVATE)
|
|
8
|
+
return jwt.sign(data, key, { algorithm: 'RS256', expiresIn: v ? v : '24h' });
|
|
9
|
+
},
|
|
10
|
+
async verifyRSA(token) {
|
|
11
|
+
// const key = ((await lib("cryptojs").decrypt(process.env.JWT_SECRET_PUBLIC, process.env.JWT_SECRET)) || '').replaceAll("__n__", "\n")
|
|
12
|
+
const key= lib("cryptojs").decodeBase64(process.env.JWT_SECRET_PUBLIC)
|
|
13
|
+
return jwt.verify(token, key);
|
|
14
|
+
},
|
|
15
|
+
auth_info(roles) {
|
|
16
|
+
return async (ctx, reply) => {
|
|
17
|
+
try {
|
|
18
|
+
const token = String(ctx?.headers?.get("authorization")|| ctx?.request.headers?.get("authorization")||' ').split(' ')[1]|| String(ctx?.query?.token||'')||''
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
const info = await this.verifyRSA(token)
|
|
22
|
+
ctx.user = info.user || info.info || info.data||info.code || info
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
if (!ctx?.user) {
|
|
26
|
+
ctx.status_=401
|
|
27
|
+
reply
|
|
28
|
+
.code(401)
|
|
29
|
+
.send({ error: '401 Unauthorized' })
|
|
30
|
+
}
|
|
31
|
+
if (roles.length==0) {
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
} else if (!roles.find(role => ctx.user.role == role)) {
|
|
35
|
+
ctx.status_=401
|
|
36
|
+
reply
|
|
37
|
+
.code(401)
|
|
38
|
+
.send({ error: '401 Unauthorized' })
|
|
39
|
+
}
|
|
40
|
+
} catch (error) {
|
|
41
|
+
|
|
42
|
+
if (roles.length>0) {
|
|
43
|
+
ctx.status_=401
|
|
44
|
+
|
|
45
|
+
return reply
|
|
46
|
+
.code(401)
|
|
47
|
+
.send({ error: '401 Unauthorized' })
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
ctx.user ={}
|
|
51
|
+
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
},
|
|
58
|
+
|
|
59
|
+
auth(roles) {
|
|
60
|
+
return async (ctx, reply) => {
|
|
61
|
+
try {
|
|
62
|
+
const token = String(ctx?.headers?.get("authorization")|| ctx?.request.headers?.get("authorization")||' ').split(' ')[1]|| String(ctx?.query?.token||'')||''
|
|
63
|
+
|
|
64
|
+
const info = await this.verifyRSA(token)
|
|
65
|
+
ctx.user = info.user || info.info || info.data||info.code || info
|
|
66
|
+
const userInfo= JSON.parse((await lib("redis").client.get("user::"+ctx.user.id))||"{}")
|
|
67
|
+
ctx.user.teams=userInfo?.teams||[]
|
|
68
|
+
|
|
69
|
+
if (!ctx?.user) {
|
|
70
|
+
ctx.status_=401
|
|
71
|
+
reply
|
|
72
|
+
.code(401)
|
|
73
|
+
.send({ error: '401 Unauthorized' })
|
|
74
|
+
}
|
|
75
|
+
if (roles.length==0) {
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
} else if (!roles.find(role => (ctx?.user?.teams||[]).find(team=>team.role==role))) {
|
|
79
|
+
ctx.status_=401
|
|
80
|
+
reply
|
|
81
|
+
.code(401)
|
|
82
|
+
.send({ error: '401 Unauthorized' })
|
|
83
|
+
}
|
|
84
|
+
} catch (error) {
|
|
85
|
+
|
|
86
|
+
console.log(error)
|
|
87
|
+
|
|
88
|
+
if (roles.length>0) {
|
|
89
|
+
ctx.status_=401
|
|
90
|
+
|
|
91
|
+
return reply
|
|
92
|
+
.code(401)
|
|
93
|
+
.send({ error: '401 Unauthorized' })
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
ctx.user ={}
|
|
97
|
+
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
},
|
|
104
|
+
|
|
105
|
+
permission_invite(roles) {
|
|
106
|
+
return async (ctx, reply) => {
|
|
107
|
+
try {
|
|
108
|
+
const token = String(ctx?.headers?.get("authorization")|| ctx?.request.headers?.get("authorization")||' ').split(' ')[1]|| String(ctx?.query?.token||'')||''
|
|
109
|
+
|
|
110
|
+
const info = await this.verifyRSA(token)
|
|
111
|
+
ctx.user = info.user || info.info || info.data||info.code || info
|
|
112
|
+
const userInfo= JSON.parse((await lib("redis").client.get("user::"+ctx.user.id))||"{}")
|
|
113
|
+
ctx.user.teams=userInfo?.teams||[]
|
|
114
|
+
if (roles.length==0) {
|
|
115
|
+
|
|
116
|
+
return
|
|
117
|
+
}
|
|
118
|
+
const {data}=ctx.body
|
|
119
|
+
ctx.user.teams=ctx.user.teams.filter((team)=>data.teams.find((t)=>t.id==team.id&& data.schoolId==team.schoolId))
|
|
120
|
+
ctx.body.data.teams==ctx.body.data.teams.filter((team)=>{
|
|
121
|
+
const t=ctx.user.teams.find((t)=>t.id==team.id && roles.find(r=>r==t.role))
|
|
122
|
+
return !!t
|
|
123
|
+
|
|
124
|
+
})
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
if (!ctx?.user) {
|
|
128
|
+
ctx.status_=401
|
|
129
|
+
reply
|
|
130
|
+
.code(401)
|
|
131
|
+
.send({ error: '401 Unauthorized' })
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
if (!roles.find(role => (ctx?.user?.teams||[]).find(team=>team.role==role))) {
|
|
137
|
+
ctx.status_=401
|
|
138
|
+
reply
|
|
139
|
+
.code(401)
|
|
140
|
+
.send({ error: '401 Unauthorized' })
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
} catch (error) {
|
|
146
|
+
|
|
147
|
+
console.log(error)
|
|
148
|
+
|
|
149
|
+
if (roles.length>0) {
|
|
150
|
+
ctx.status_=401
|
|
151
|
+
|
|
152
|
+
return reply
|
|
153
|
+
.code(401)
|
|
154
|
+
.send({ error: '401 Unauthorized' })
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
ctx.user ={}
|
|
158
|
+
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
},
|
|
165
|
+
auth1(roles) {
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
return async (request, reply) => {
|
|
170
|
+
try {
|
|
171
|
+
const token = String(request.headers['authorization']).split(' ')[1]
|
|
172
|
+
const info = await this.verifyRSA(token)
|
|
173
|
+
request.user = info.user || info.info || info.data||info.code || info
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
if (!request?.user) {
|
|
177
|
+
reply
|
|
178
|
+
.code(401)
|
|
179
|
+
.send({ error: '401 Unauthorized' })
|
|
180
|
+
}
|
|
181
|
+
if (roles.length==0) {
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
} else if (!roles.find(role => request.user.role == role)) {
|
|
185
|
+
reply
|
|
186
|
+
.code(401)
|
|
187
|
+
.send({ error: '401 Unauthorized' })
|
|
188
|
+
}
|
|
189
|
+
} catch (error) {
|
|
190
|
+
|
|
191
|
+
reply
|
|
192
|
+
.code(401)
|
|
193
|
+
.send({ error: '401 Unauthorized' })
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
},
|
|
200
|
+
qrcode() {
|
|
201
|
+
|
|
202
|
+
return async (request, reply) => {
|
|
203
|
+
const infoStr = String(request.query['identifier'] || '')
|
|
204
|
+
const res = "U2FsdGVkX182xxWCbg9dZxlmmhdMcGGs2xzfdfAXv9FUr/odoyBb4T/yWBQip45iQg5NZmRrrUgRKI3JjL2o5c3rQmKhl7fkKDETT3pF9aorvAYTllBElYq7lUgczSpUhyxPtkpCbrOhgbvHuX8pwCeEnptiEL4CZgorj26jQUO17IlSk1AY2bjwlNgAQuKEgrfacJVcNyn9LtKHHHIQP5LYKxxB5P1oXNEc540n8tcu7+og5x/Pnb9pnm79ZKXH"
|
|
205
|
+
|
|
206
|
+
const decrypt = lib("cryptojs").decrypt(res)
|
|
207
|
+
console.log(infoStr, 'd', decrypt)
|
|
208
|
+
if (!decrypt) {
|
|
209
|
+
reply
|
|
210
|
+
.code(401)
|
|
211
|
+
.send({ error: '401 Unauthorized' })
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
request.user = (JSON.parse(decrypt)).identifier || {}
|
|
215
|
+
if (!request.user.code) {
|
|
216
|
+
reply
|
|
217
|
+
.code(401)
|
|
218
|
+
.send({ error: '401 Unauthorized' })
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
},
|
|
225
|
+
async forgot(info, e = (5 * 60 * 60) + "s",n=6) {
|
|
226
|
+
const verificationCode = lib('generate').number(n)
|
|
227
|
+
return {
|
|
228
|
+
verificationCode,
|
|
229
|
+
verificationJwt: await this.tokenRSA({
|
|
230
|
+
code: { verificationCode, password: true,...info, userId: info.id }
|
|
231
|
+
}, e)
|
|
232
|
+
}
|
|
233
|
+
},
|
|
234
|
+
async code(user, e = (5 * 60 * 60) + "s") {
|
|
235
|
+
return await this.tokenRSA({ user, login: true }, e)
|
|
236
|
+
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
})
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
// websocket-manager.js
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Cria um gerenciador de WebSockets.
|
|
5
|
+
* Este gerenciador armazena a configuração das rotas WS (autenticação, conexão, etc.)
|
|
6
|
+
* e a sincroniza com um adaptador específico (como o do Elysia).
|
|
7
|
+
*
|
|
8
|
+
* @param {object} adapter - O adaptador que irá lidar com a implementação do WebSocket (ex: adapterElysia).
|
|
9
|
+
* @returns {object} - Um objeto com métodos para configurar e sincronizar as rotas WS.
|
|
10
|
+
*/
|
|
11
|
+
export default ({ adapter }) => {
|
|
12
|
+
// Armazena a configuração de cada path de WebSocket.
|
|
13
|
+
// Estrutura: { "/path": { connections: {}, events: {}, rooms: {}, room_handlers: {}, auth_fn, connection_fn } }
|
|
14
|
+
const wsConfig = {};
|
|
15
|
+
|
|
16
|
+
return {
|
|
17
|
+
/**
|
|
18
|
+
* Sincroniza todas as configurações de rotas definidas com `of()` com o adaptador.
|
|
19
|
+
* Deve ser chamado após todas as rotas terem sido definidas.
|
|
20
|
+
*/
|
|
21
|
+
async sync() {
|
|
22
|
+
for (const [path, config] of Object.entries(wsConfig)) {
|
|
23
|
+
adapter.addWs(path, config);
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Define uma nova rota de WebSocket.
|
|
29
|
+
* @param {string} path - O caminho da rota (ex: "/chat").
|
|
30
|
+
* @returns {object} - Um objeto com métodos para configurar a rota (auth, connection, to, broadcast).
|
|
31
|
+
*/
|
|
32
|
+
of(path = "/") {
|
|
33
|
+
if (!wsConfig[path]) {
|
|
34
|
+
wsConfig[path] = {
|
|
35
|
+
connections: {},
|
|
36
|
+
events: {},
|
|
37
|
+
rooms: {},
|
|
38
|
+
room_handlers: {},
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const output = {
|
|
43
|
+
auth(fn) {
|
|
44
|
+
wsConfig[path].auth_fn = fn;
|
|
45
|
+
return output;
|
|
46
|
+
},
|
|
47
|
+
|
|
48
|
+
connection(fn) {
|
|
49
|
+
wsConfig[path].connection_fn = fn;
|
|
50
|
+
return output;
|
|
51
|
+
},
|
|
52
|
+
|
|
53
|
+
to(roomName) {
|
|
54
|
+
const roomInterface = {
|
|
55
|
+
on(eventName, fn) {
|
|
56
|
+
if (!wsConfig[path].room_handlers[roomName]) {
|
|
57
|
+
wsConfig[path].room_handlers[roomName] = {};
|
|
58
|
+
}
|
|
59
|
+
if (!wsConfig[path].room_handlers[roomName][eventName]) {
|
|
60
|
+
wsConfig[path].room_handlers[roomName][eventName] = new Map();
|
|
61
|
+
}
|
|
62
|
+
wsConfig[path].room_handlers[roomName][eventName].set(fn, fn);
|
|
63
|
+
return roomInterface;
|
|
64
|
+
},
|
|
65
|
+
off(eventName, fn) {
|
|
66
|
+
const handlers = wsConfig[path].room_handlers[roomName]?.[eventName];
|
|
67
|
+
if (handlers && handlers.has(fn)) {
|
|
68
|
+
handlers.delete(fn);
|
|
69
|
+
if (handlers.size === 0) {
|
|
70
|
+
delete wsConfig[path].room_handlers[roomName][eventName];
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return roomInterface;
|
|
74
|
+
},
|
|
75
|
+
emit(eventName, data) {
|
|
76
|
+
const members = wsConfig[path].rooms[roomName];
|
|
77
|
+
if (!members) return;
|
|
78
|
+
members.forEach(memberId => {
|
|
79
|
+
const targetSocket = wsConfig[path].connections[memberId];
|
|
80
|
+
if (targetSocket) {
|
|
81
|
+
targetSocket.emit(eventName, data);
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
},
|
|
85
|
+
};
|
|
86
|
+
return roomInterface;
|
|
87
|
+
},
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* NOVO: Envia um evento (broadcast) do servidor para TODOS os clientes conectados nesta rota.
|
|
91
|
+
* @param {string} eventName - O nome do evento a ser enviado.
|
|
92
|
+
* @param {any} data - Os dados do evento.
|
|
93
|
+
* @returns {object} - Retorna `output` para permitir encadeamento.
|
|
94
|
+
*/
|
|
95
|
+
emit(eventName, data) {
|
|
96
|
+
const allConnections = wsConfig[path].connections;
|
|
97
|
+
// Itera sobre todos os sockets conectados a este path
|
|
98
|
+
for (const socket of Object.values(allConnections)) {
|
|
99
|
+
// Usa o método emit do socket individual para garantir a formatação correta
|
|
100
|
+
socket.emit(eventName, data);
|
|
101
|
+
}
|
|
102
|
+
return output;
|
|
103
|
+
},
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
return output;
|
|
107
|
+
},
|
|
108
|
+
};
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Adaptador para integrar o gerenciador de WebSockets com o framework Elysia.
|
|
114
|
+
* @param {object} server - A instância do servidor Elysia.
|
|
115
|
+
* @returns {object} - Um objeto com o método `addWs` para registrar as rotas.
|
|
116
|
+
*/
|
|
117
|
+
export const adapterElysia = (server) => {
|
|
118
|
+
return {
|
|
119
|
+
async addWs(path, config) {
|
|
120
|
+
server.ws(path, {
|
|
121
|
+
async open(ws) {
|
|
122
|
+
let isAuthenticated = true;
|
|
123
|
+
|
|
124
|
+
const socket = {
|
|
125
|
+
id: ws.id,
|
|
126
|
+
request: ws.data,
|
|
127
|
+
close: () => ws.close(),
|
|
128
|
+
rooms: new Set(),
|
|
129
|
+
_path: path,
|
|
130
|
+
|
|
131
|
+
send: (obj) => ws.send(JSON.stringify(obj)),
|
|
132
|
+
emit(eventName, data) {
|
|
133
|
+
this.send({ event: eventName, data });
|
|
134
|
+
},
|
|
135
|
+
on(eventName, fn) {
|
|
136
|
+
if (!config.events[ws.id]) {
|
|
137
|
+
config.events[ws.id] = {};
|
|
138
|
+
}
|
|
139
|
+
if (!config.events[ws.id][eventName]) {
|
|
140
|
+
config.events[ws.id][eventName] = [];
|
|
141
|
+
}
|
|
142
|
+
config.events[ws.id][eventName].push(fn);
|
|
143
|
+
},
|
|
144
|
+
join(roomName) {
|
|
145
|
+
if (!config.rooms[roomName]) {
|
|
146
|
+
config.rooms[roomName] = new Set();
|
|
147
|
+
}
|
|
148
|
+
config.rooms[roomName].add(this.id);
|
|
149
|
+
this.rooms.add(roomName);
|
|
150
|
+
},
|
|
151
|
+
leave(roomName) {
|
|
152
|
+
if (config.rooms[roomName]) {
|
|
153
|
+
config.rooms[roomName].delete(this.id);
|
|
154
|
+
if (config.rooms[roomName].size === 0) {
|
|
155
|
+
delete config.rooms[roomName];
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
this.rooms.delete(roomName);
|
|
159
|
+
},
|
|
160
|
+
to(roomName) {
|
|
161
|
+
return {
|
|
162
|
+
emit: (eventName, data) => {
|
|
163
|
+
const members = config.rooms[roomName];
|
|
164
|
+
if (!members) return;
|
|
165
|
+
members.forEach(memberId => {
|
|
166
|
+
if (memberId !== this.id) {
|
|
167
|
+
const targetSocket = config.connections[memberId];
|
|
168
|
+
if (targetSocket) {
|
|
169
|
+
targetSocket.emit(eventName, data);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
},
|
|
174
|
+
};
|
|
175
|
+
},
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
config.connections[ws.id] = socket;
|
|
179
|
+
config.events[ws.id] = {};
|
|
180
|
+
|
|
181
|
+
if (config.auth_fn) {
|
|
182
|
+
try {
|
|
183
|
+
await config.auth_fn(socket, (error) => {
|
|
184
|
+
if (error) {
|
|
185
|
+
ws.close();
|
|
186
|
+
isAuthenticated = false;
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
} catch (error) {
|
|
190
|
+
console.error("Erro durante a autenticação do WebSocket:", error);
|
|
191
|
+
ws.close();
|
|
192
|
+
isAuthenticated = false;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
if (!isAuthenticated) {
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
if (config.connection_fn) {
|
|
201
|
+
await config.connection_fn(socket);
|
|
202
|
+
}
|
|
203
|
+
},
|
|
204
|
+
|
|
205
|
+
async message(ws, message) {
|
|
206
|
+
try {
|
|
207
|
+
const event = message;
|
|
208
|
+
const senderSocket = config.connections[ws.id];
|
|
209
|
+
if (!senderSocket) return;
|
|
210
|
+
|
|
211
|
+
const connectionEvents = config.events[ws.id];
|
|
212
|
+
if (connectionEvents && connectionEvents[event.event]) {
|
|
213
|
+
connectionEvents[event.event].forEach(fn => fn(event.data));
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
for (const roomName of senderSocket.rooms) {
|
|
217
|
+
const roomHandlers = config.room_handlers[roomName]?.[event.event];
|
|
218
|
+
if (roomHandlers) {
|
|
219
|
+
roomHandlers.forEach(fn => {
|
|
220
|
+
fn(senderSocket, event.data);
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
} catch (error) {
|
|
226
|
+
console.error("Falha ao processar a mensagem do WebSocket:", error);
|
|
227
|
+
}
|
|
228
|
+
},
|
|
229
|
+
|
|
230
|
+
close(ws) {
|
|
231
|
+
const socket = config.connections[ws.id];
|
|
232
|
+
if (!socket) return;
|
|
233
|
+
|
|
234
|
+
const disconnectListeners = config.events[ws.id]?.disconnect;
|
|
235
|
+
if (disconnectListeners) {
|
|
236
|
+
disconnectListeners.forEach(fn => fn({ id: ws.id }));
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
socket.rooms.forEach(roomName => socket.leave(roomName));
|
|
240
|
+
|
|
241
|
+
delete config.events[ws.id];
|
|
242
|
+
delete config.connections[ws.id];
|
|
243
|
+
},
|
|
244
|
+
});
|
|
245
|
+
},
|
|
246
|
+
};
|
|
247
|
+
};
|
package/esm/core/serverCore.js
CHANGED
|
@@ -67,12 +67,14 @@ export default ({ core }) => {
|
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
const routers = await createCoreRouter({}, {})
|
|
70
|
+
|
|
71
|
+
|
|
70
72
|
const wsServer = await createCoreSocket({}, {})
|
|
71
73
|
try {
|
|
72
74
|
|
|
73
75
|
const serve = (await core.fileCore.import(rootFile, {
|
|
74
|
-
util:
|
|
75
|
-
lib:
|
|
76
|
+
util: core.app.util,
|
|
77
|
+
lib: core.app.lib,
|
|
76
78
|
routers,
|
|
77
79
|
ws: wsServer
|
|
78
80
|
}))
|
package/esm/fileCore.js
CHANGED
|
@@ -15,5 +15,5 @@ export default {
|
|
|
15
15
|
if (!this.exist(paths)) return []
|
|
16
16
|
return fs.readdirSync(path.resolve(this.path + paths))
|
|
17
17
|
},
|
|
18
|
-
bin: fs.existsSync(process.cwd() + '/esm') ? '/esm' : '/node_modules/
|
|
18
|
+
bin: fs.existsSync(process.cwd() + '/esm') ? '/esm' : '/node_modules/org-core-js/esm',
|
|
19
19
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "org-core-js",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "src/start.js",
|
|
6
6
|
"scripts": {
|
|
@@ -28,6 +28,10 @@
|
|
|
28
28
|
"./forawait": {
|
|
29
29
|
"import": "./esm/forawait.js",
|
|
30
30
|
"require": "./cjs/forawait.js"
|
|
31
|
+
},
|
|
32
|
+
"./plugins": {
|
|
33
|
+
"import": "./esm/core/plugins.js",
|
|
34
|
+
"require": "./cjs/core/plugins.js"
|
|
31
35
|
},
|
|
32
36
|
"./fileCore": {
|
|
33
37
|
"import": "./esm/fileCore.js",
|