@rebasepro/server-core 0.3.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +62 -25
- package/dist/common/src/collections/default-collections.d.ts +5 -8
- package/dist/common/src/data/query_builder.d.ts +6 -2
- package/dist/common/src/util/permissions.d.ts +14 -6
- package/dist/index.es.js +393 -315
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +393 -315
- package/dist/index.umd.js.map +1 -1
- package/dist/server-core/src/api/errors.d.ts +15 -0
- package/dist/server-core/src/api/rest/query-parser.d.ts +2 -0
- package/dist/server-core/src/api/types.d.ts +2 -1
- package/dist/server-core/src/auth/jwt.d.ts +10 -0
- package/dist/server-core/src/email/types.d.ts +1 -0
- package/dist/server-core/src/init.d.ts +31 -1
- package/dist/types/src/controllers/auth.d.ts +2 -2
- package/dist/types/src/controllers/client.d.ts +25 -40
- package/dist/types/src/controllers/data.d.ts +21 -3
- package/dist/types/src/controllers/data_driver.d.ts +5 -0
- package/dist/types/src/controllers/email.d.ts +2 -0
- package/dist/types/src/types/auth_adapter.d.ts +3 -56
- package/dist/types/src/types/backend.d.ts +38 -3
- package/dist/types/src/types/backend_hooks.d.ts +2 -17
- package/dist/types/src/types/collections.d.ts +30 -6
- package/dist/types/src/types/entity_views.d.ts +19 -28
- package/dist/types/src/types/properties.d.ts +9 -15
- package/dist/types/src/types/user_management_delegate.d.ts +16 -53
- package/dist/types/src/users/index.d.ts +0 -1
- package/dist/types/src/users/user.d.ts +0 -1
- package/package.json +5 -5
- package/src/api/errors.ts +20 -1
- package/src/api/openapi-generator.ts +1 -1
- package/src/api/rest/api-generator.ts +82 -24
- package/src/api/rest/query-parser.ts +184 -63
- package/src/api/server.ts +1 -1
- package/src/api/types.ts +2 -1
- package/src/auth/admin-routes.ts +2 -91
- package/src/auth/builtin-auth-adapter.ts +9 -70
- package/src/auth/custom-auth-adapter.ts +1 -1
- package/src/auth/jwt.ts +10 -0
- package/src/auth/routes.ts +5 -9
- package/src/email/smtp-email-service.ts +31 -0
- package/src/email/types.ts +1 -0
- package/src/init.ts +135 -31
- package/src/storage/image-transform.ts +2 -1
- package/test/admin-routes.test.ts +0 -169
- package/test/backend-hooks-admin.test.ts +0 -25
- package/test/custom-auth-adapter.test.ts +2 -10
- package/test/smtp-email-service.test.ts +169 -0
- package/dist/types/src/users/roles.d.ts +0 -14
- package/test.ts +0 -6
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { SMTPEmailService } from "../src/email/smtp-email-service";
|
|
2
|
+
import nodemailer from "nodemailer";
|
|
3
|
+
|
|
4
|
+
jest.mock("nodemailer", () => {
|
|
5
|
+
const mockTransporter = {
|
|
6
|
+
verify: jest.fn().mockResolvedValue(true),
|
|
7
|
+
sendMail: jest.fn().mockResolvedValue(true),
|
|
8
|
+
};
|
|
9
|
+
return {
|
|
10
|
+
createTransport: jest.fn().mockReturnValue(mockTransporter),
|
|
11
|
+
};
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
describe("SMTPEmailService", () => {
|
|
15
|
+
let mockCreateTransport: jest.Mock;
|
|
16
|
+
let mockTransporter: any;
|
|
17
|
+
|
|
18
|
+
beforeEach(() => {
|
|
19
|
+
jest.clearAllMocks();
|
|
20
|
+
mockCreateTransport = nodemailer.createTransport as jest.Mock;
|
|
21
|
+
mockTransporter = mockCreateTransport({} as any); // gets the mocked object
|
|
22
|
+
mockCreateTransport.mockClear();
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it("should create transport with explicit name", () => {
|
|
26
|
+
new SMTPEmailService({
|
|
27
|
+
from: "test@example.com",
|
|
28
|
+
smtp: {
|
|
29
|
+
host: "smtp.example.com",
|
|
30
|
+
port: 587,
|
|
31
|
+
name: "explicit-hostname",
|
|
32
|
+
},
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
expect(mockCreateTransport).toHaveBeenCalledWith(
|
|
36
|
+
expect.objectContaining({
|
|
37
|
+
name: "explicit-hostname",
|
|
38
|
+
host: "smtp.example.com",
|
|
39
|
+
port: 587,
|
|
40
|
+
})
|
|
41
|
+
);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it("should infer name from FRONTEND_URL if smtp.name is undefined", () => {
|
|
45
|
+
const originalFrontendUrl = process.env.FRONTEND_URL;
|
|
46
|
+
process.env.FRONTEND_URL = "https://frontend-url.com/some-path";
|
|
47
|
+
|
|
48
|
+
try {
|
|
49
|
+
new SMTPEmailService({
|
|
50
|
+
from: "test@example.com",
|
|
51
|
+
smtp: {
|
|
52
|
+
host: "smtp.example.com",
|
|
53
|
+
port: 587,
|
|
54
|
+
},
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
expect(mockCreateTransport).toHaveBeenCalledWith(
|
|
58
|
+
expect.objectContaining({
|
|
59
|
+
name: "frontend-url.com",
|
|
60
|
+
})
|
|
61
|
+
);
|
|
62
|
+
} finally {
|
|
63
|
+
process.env.FRONTEND_URL = originalFrontendUrl;
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it("should infer name from resetPasswordUrl if FRONTEND_URL and smtp.name are undefined", () => {
|
|
68
|
+
const originalFrontendUrl = process.env.FRONTEND_URL;
|
|
69
|
+
delete process.env.FRONTEND_URL;
|
|
70
|
+
|
|
71
|
+
try {
|
|
72
|
+
new SMTPEmailService({
|
|
73
|
+
from: "test@example.com",
|
|
74
|
+
smtp: {
|
|
75
|
+
host: "smtp.example.com",
|
|
76
|
+
port: 587,
|
|
77
|
+
},
|
|
78
|
+
resetPasswordUrl: "http://reset-password-url.org",
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
expect(mockCreateTransport).toHaveBeenCalledWith(
|
|
82
|
+
expect.objectContaining({
|
|
83
|
+
name: "reset-password-url.org",
|
|
84
|
+
})
|
|
85
|
+
);
|
|
86
|
+
} finally {
|
|
87
|
+
process.env.FRONTEND_URL = originalFrontendUrl;
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it("should infer name from verifyEmailUrl if FRONTEND_URL, resetPasswordUrl and smtp.name are undefined", () => {
|
|
92
|
+
const originalFrontendUrl = process.env.FRONTEND_URL;
|
|
93
|
+
delete process.env.FRONTEND_URL;
|
|
94
|
+
|
|
95
|
+
try {
|
|
96
|
+
new SMTPEmailService({
|
|
97
|
+
from: "test@example.com",
|
|
98
|
+
smtp: {
|
|
99
|
+
host: "smtp.example.com",
|
|
100
|
+
port: 587,
|
|
101
|
+
},
|
|
102
|
+
verifyEmailUrl: "verify-email-url.net/auth",
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
expect(mockCreateTransport).toHaveBeenCalledWith(
|
|
106
|
+
expect.objectContaining({
|
|
107
|
+
name: "verify-email-url.net",
|
|
108
|
+
})
|
|
109
|
+
);
|
|
110
|
+
} finally {
|
|
111
|
+
process.env.FRONTEND_URL = originalFrontendUrl;
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
it("should leave name undefined if no URLs are provided", () => {
|
|
116
|
+
const originalFrontendUrl = process.env.FRONTEND_URL;
|
|
117
|
+
delete process.env.FRONTEND_URL;
|
|
118
|
+
|
|
119
|
+
try {
|
|
120
|
+
new SMTPEmailService({
|
|
121
|
+
from: "test@example.com",
|
|
122
|
+
smtp: {
|
|
123
|
+
host: "smtp.example.com",
|
|
124
|
+
port: 587,
|
|
125
|
+
},
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
expect(mockCreateTransport).toHaveBeenCalledWith(
|
|
129
|
+
expect.objectContaining({
|
|
130
|
+
name: undefined,
|
|
131
|
+
})
|
|
132
|
+
);
|
|
133
|
+
} finally {
|
|
134
|
+
process.env.FRONTEND_URL = originalFrontendUrl;
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
it("should successfully verify SMTP connection", async () => {
|
|
139
|
+
mockTransporter.verify.mockResolvedValueOnce(true);
|
|
140
|
+
|
|
141
|
+
const service = new SMTPEmailService({
|
|
142
|
+
from: "test@example.com",
|
|
143
|
+
smtp: {
|
|
144
|
+
host: "smtp.example.com",
|
|
145
|
+
port: 587,
|
|
146
|
+
},
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
const verified = await service.verifyConnection();
|
|
150
|
+
expect(verified).toBe(true);
|
|
151
|
+
expect(mockTransporter.verify).toHaveBeenCalled();
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
it("should return false if SMTP connection verification fails", async () => {
|
|
155
|
+
mockTransporter.verify.mockRejectedValueOnce(new Error("Connection timeout"));
|
|
156
|
+
|
|
157
|
+
const service = new SMTPEmailService({
|
|
158
|
+
from: "test@example.com",
|
|
159
|
+
smtp: {
|
|
160
|
+
host: "smtp.example.com",
|
|
161
|
+
port: 587,
|
|
162
|
+
},
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
const verified = await service.verifyConnection();
|
|
166
|
+
expect(verified).toBe(false);
|
|
167
|
+
expect(mockTransporter.verify).toHaveBeenCalled();
|
|
168
|
+
});
|
|
169
|
+
});
|