@crossauth/sveltekit 1.1.0 → 1.1.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/dist/index.d.ts +1 -1
- package/dist/index.js +16 -6181
- package/dist/sveltekitadminclientendpoints.d.ts +13 -12
- package/dist/sveltekitadminclientendpoints.js +187 -0
- package/dist/sveltekitadminendpoints.d.ts +5 -4
- package/dist/sveltekitadminendpoints.js +766 -0
- package/dist/sveltekitapikey.d.ts +4 -4
- package/dist/sveltekitapikey.js +81 -0
- package/dist/sveltekitoauthclient.d.ts +6 -5
- package/dist/sveltekitoauthclient.js +2309 -0
- package/dist/sveltekitoauthserver.d.ts +4 -4
- package/dist/sveltekitoauthserver.js +1350 -0
- package/dist/sveltekitresserver.d.ts +6 -5
- package/dist/sveltekitresserver.js +286 -0
- package/dist/sveltekitserver.d.ts +11 -10
- package/dist/sveltekitserver.js +393 -0
- package/dist/sveltekitsession.d.ts +5 -5
- package/dist/sveltekitsession.js +1112 -0
- package/dist/sveltekitsessionadapter.d.ts +2 -3
- package/dist/sveltekitsessionadapter.js +2 -0
- package/dist/sveltekitsharedclientendpoints.d.ts +7 -6
- package/dist/sveltekitsharedclientendpoints.js +630 -0
- package/dist/sveltekituserclientendpoints.d.ts +13 -12
- package/dist/sveltekituserclientendpoints.js +270 -0
- package/dist/sveltekituserendpoints.d.ts +6 -5
- package/dist/sveltekituserendpoints.js +1813 -0
- package/dist/tests/sveltekitadminclientendpoints.test.js +330 -0
- package/dist/tests/sveltekitadminendpoints.test.js +242 -0
- package/dist/tests/sveltekitapikeyserver.test.js +44 -0
- package/dist/tests/sveltekitoauthclient.test.d.ts +5 -5
- package/dist/tests/sveltekitoauthclient.test.js +1016 -0
- package/dist/tests/sveltekitoauthresserver.test.d.ts +4 -4
- package/dist/tests/sveltekitoauthresserver.test.js +185 -0
- package/dist/tests/sveltekitoauthserver.test.js +673 -0
- package/dist/tests/sveltekituserclientendpoints.test.js +244 -0
- package/dist/tests/sveltekituserendpoints.test.js +152 -0
- package/dist/tests/sveltemock.test.js +36 -0
- package/dist/tests/sveltemocks.d.ts +2 -3
- package/dist/tests/sveltemocks.js +114 -0
- package/dist/tests/sveltesessionhooks.test.js +224 -0
- package/dist/tests/testshared.d.ts +8 -8
- package/dist/tests/testshared.js +344 -0
- package/dist/utils.d.ts +1 -2
- package/dist/utils.js +123 -0
- package/package.json +6 -4
- package/dist/index.cjs +0 -1
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
// Copyright (c) 2026 Matthew Baker. All rights reserved. Licenced under the Apache Licence 2.0. See LICENSE file
|
|
2
|
+
import { MockRequestEvent } from './sveltemocks';
|
|
3
|
+
import { test, expect } from 'vitest';
|
|
4
|
+
import { makeServer, getCsrfToken, login } from './testshared';
|
|
5
|
+
export var passwordResetData;
|
|
6
|
+
test('SvelteKitUserClientEndpoints.selectClients', async () => {
|
|
7
|
+
const { server, resolver, handle, } = await makeServer();
|
|
8
|
+
// log in
|
|
9
|
+
let resp = await login(server, resolver, handle);
|
|
10
|
+
let loginEvent = resp.event;
|
|
11
|
+
loginEvent = resp.event;
|
|
12
|
+
const { csrfToken, csrfCookieValue } = await getCsrfToken(server, resolver, handle);
|
|
13
|
+
let sessionCookieValue = loginEvent.cookies.get("SESSIONID");
|
|
14
|
+
let sessionId = server.sessionServer?.sessionManager.getSessionId(sessionCookieValue ?? "");
|
|
15
|
+
// select clients
|
|
16
|
+
let getRequest = new Request("http://ex.com/oauth/clients", {
|
|
17
|
+
method: "POST",
|
|
18
|
+
body: "csrfToken=" + csrfToken,
|
|
19
|
+
headers: [
|
|
20
|
+
["cookie", "CSRFTOKEN=" + csrfCookieValue],
|
|
21
|
+
["cookie", "SESSIONID=" + sessionCookieValue],
|
|
22
|
+
["content-type", "application/x-www-form-urlencoded"],
|
|
23
|
+
]
|
|
24
|
+
});
|
|
25
|
+
let event = new MockRequestEvent("1", getRequest, { id: "bob" });
|
|
26
|
+
event.locals.csrfToken = csrfToken;
|
|
27
|
+
event.locals.sessionId = sessionId;
|
|
28
|
+
event.locals.authType = "cookie";
|
|
29
|
+
event.locals.user = loginEvent.locals.user;
|
|
30
|
+
let resp1 = await server.sessionServer?.userClientEndpoints.searchClients(event);
|
|
31
|
+
expect(resp1?.ok).toBe(true);
|
|
32
|
+
expect(resp1?.clients?.length).toBe(1);
|
|
33
|
+
});
|
|
34
|
+
test('SvelteKitUserClientEndpoints.updateClient', async () => {
|
|
35
|
+
const { server, resolver, handle } = await makeServer();
|
|
36
|
+
// log in
|
|
37
|
+
let resp = await login(server, resolver, handle);
|
|
38
|
+
let loginEvent = resp.event;
|
|
39
|
+
loginEvent = resp.event;
|
|
40
|
+
const { csrfToken, csrfCookieValue } = await getCsrfToken(server, resolver, handle);
|
|
41
|
+
let sessionCookieValue = loginEvent.cookies.get("SESSIONID");
|
|
42
|
+
let sessionId = server.sessionServer?.sessionManager.getSessionId(sessionCookieValue ?? "");
|
|
43
|
+
let getRequest = new Request("http://ex.com/oauth/clients", {
|
|
44
|
+
method: "GET",
|
|
45
|
+
headers: [
|
|
46
|
+
["cookie", "CSRFTOKEN=" + csrfCookieValue],
|
|
47
|
+
["cookie", "SESSIONID=" + sessionCookieValue],
|
|
48
|
+
["content-type", "application/x-www-form-urlencoded"],
|
|
49
|
+
]
|
|
50
|
+
});
|
|
51
|
+
let event = new MockRequestEvent("1", getRequest, { client_id: "ABC" });
|
|
52
|
+
event.locals.csrfToken = csrfToken;
|
|
53
|
+
let status = 200;
|
|
54
|
+
let resp1 = {};
|
|
55
|
+
try {
|
|
56
|
+
resp1 = await server.sessionServer?.userClientEndpoints.updateClientEndpoint.load(event);
|
|
57
|
+
}
|
|
58
|
+
catch (e) {
|
|
59
|
+
if (e && typeof (e) == "object" && "status" in e && typeof (e.status) == "number")
|
|
60
|
+
status = e.status;
|
|
61
|
+
}
|
|
62
|
+
expect(status).toBe(302);
|
|
63
|
+
event = new MockRequestEvent("1", getRequest, { client_id: "ABC" });
|
|
64
|
+
event.locals.csrfToken = csrfToken;
|
|
65
|
+
event.locals.sessionId = sessionId;
|
|
66
|
+
event.locals.authType = "cookie";
|
|
67
|
+
event.locals.user = loginEvent.locals.user;
|
|
68
|
+
status = 200;
|
|
69
|
+
try {
|
|
70
|
+
resp1 = await server.sessionServer?.userClientEndpoints.updateClientEndpoint.load(event);
|
|
71
|
+
}
|
|
72
|
+
catch (e) {
|
|
73
|
+
if (e && typeof (e) == "object" && "status" in e && typeof (e.status) == "number")
|
|
74
|
+
status = e.status;
|
|
75
|
+
}
|
|
76
|
+
expect(status).toBe(401);
|
|
77
|
+
event = new MockRequestEvent("1", getRequest, { client_id: "bob_ABC" });
|
|
78
|
+
event.locals.csrfToken = csrfToken;
|
|
79
|
+
event.locals.sessionId = sessionId;
|
|
80
|
+
event.locals.authType = "cookie";
|
|
81
|
+
event.locals.user = loginEvent.locals.user;
|
|
82
|
+
resp1 = await server.sessionServer?.userClientEndpoints.updateClientEndpoint.load(event);
|
|
83
|
+
expect(resp1?.ok).toBe(true);
|
|
84
|
+
let postRequest = new Request("http://ex.com/oauth/clients", {
|
|
85
|
+
method: "POST",
|
|
86
|
+
body: "csrfToken=" + csrfToken + "&client_name=newName&confidential=on&redirect_uri=http://uri1.com/redirect&authorizationCode=on",
|
|
87
|
+
headers: [
|
|
88
|
+
["cookie", "CSRFTOKEN=" + csrfCookieValue],
|
|
89
|
+
["cookie", "SESSIONID=" + sessionCookieValue],
|
|
90
|
+
["content-type", "application/x-www-form-urlencoded"],
|
|
91
|
+
]
|
|
92
|
+
});
|
|
93
|
+
event = new MockRequestEvent("1", postRequest, { client_id: "bob_ABC" });
|
|
94
|
+
event.locals.csrfToken = csrfToken;
|
|
95
|
+
event.locals.sessionId = sessionId;
|
|
96
|
+
event.locals.authType = "cookie";
|
|
97
|
+
event.locals.user = loginEvent.locals.user;
|
|
98
|
+
resp1 = await server.sessionServer?.userClientEndpoints.updateClientEndpoint.actions.default(event);
|
|
99
|
+
expect(resp1?.ok).toBe(true);
|
|
100
|
+
expect(resp1?.client?.client_name).toBe("newName");
|
|
101
|
+
expect(resp1?.plaintextSecret).toBeUndefined();
|
|
102
|
+
expect(resp1?.client?.client_secret).toContain("pbkdf2:sha256");
|
|
103
|
+
postRequest = new Request("http://ex.com/oauth/clients", {
|
|
104
|
+
method: "POST",
|
|
105
|
+
body: "csrfToken=" + csrfToken + "&client_name=newName&confidential=on&redirect_uri=http://uri1.com/redirect&authorizationCode=on&resetSecret=on",
|
|
106
|
+
headers: [
|
|
107
|
+
["cookie", "CSRFTOKEN=" + csrfCookieValue],
|
|
108
|
+
["cookie", "SESSIONID=" + sessionCookieValue],
|
|
109
|
+
["content-type", "application/x-www-form-urlencoded"],
|
|
110
|
+
]
|
|
111
|
+
});
|
|
112
|
+
event = new MockRequestEvent("1", postRequest, { client_id: "bob_ABC" });
|
|
113
|
+
event.locals.csrfToken = csrfToken;
|
|
114
|
+
event.locals.sessionId = sessionId;
|
|
115
|
+
event.locals.authType = "cookie";
|
|
116
|
+
event.locals.user = loginEvent.locals.user;
|
|
117
|
+
resp1 = await server.sessionServer?.userClientEndpoints.updateClientEndpoint.actions.default(event);
|
|
118
|
+
expect(resp1?.ok).toBe(true);
|
|
119
|
+
expect(resp1?.plaintextSecret).toBeDefined();
|
|
120
|
+
expect(resp1?.client?.client_secret).not.toContain("pbkdf2:sha256");
|
|
121
|
+
});
|
|
122
|
+
test('SvelteKitUserClientEndpoints.deleteClient', async () => {
|
|
123
|
+
const { server, resolver, handle } = await makeServer();
|
|
124
|
+
// log in
|
|
125
|
+
let resp = await login(server, resolver, handle);
|
|
126
|
+
let loginEvent = resp.event;
|
|
127
|
+
loginEvent = resp.event;
|
|
128
|
+
const { csrfToken, csrfCookieValue } = await getCsrfToken(server, resolver, handle);
|
|
129
|
+
let sessionCookieValue = loginEvent.cookies.get("SESSIONID");
|
|
130
|
+
let sessionId = server.sessionServer?.sessionManager.getSessionId(sessionCookieValue ?? "");
|
|
131
|
+
let getRequest = new Request("http://ex.com/oauth/clients", {
|
|
132
|
+
method: "GET",
|
|
133
|
+
headers: [
|
|
134
|
+
["cookie", "CSRFTOKEN=" + csrfCookieValue],
|
|
135
|
+
["cookie", "SESSIONID=" + sessionCookieValue],
|
|
136
|
+
["content-type", "application/x-www-form-urlencoded"],
|
|
137
|
+
]
|
|
138
|
+
});
|
|
139
|
+
let event = new MockRequestEvent("1", getRequest, { client_id: "ABC" });
|
|
140
|
+
event.locals.csrfToken = csrfToken;
|
|
141
|
+
let status = 200;
|
|
142
|
+
let resp1 = {};
|
|
143
|
+
try {
|
|
144
|
+
resp1 = await server.sessionServer?.userClientEndpoints.deleteClientEndpoint.load(event);
|
|
145
|
+
}
|
|
146
|
+
catch (e) {
|
|
147
|
+
if (e && typeof (e) == "object" && "status" in e && typeof (e.status) == "number")
|
|
148
|
+
status = e.status;
|
|
149
|
+
}
|
|
150
|
+
expect(status).toBe(302);
|
|
151
|
+
event = new MockRequestEvent("1", getRequest, { client_id: "ABC" });
|
|
152
|
+
event.locals.csrfToken = csrfToken;
|
|
153
|
+
event.locals.sessionId = sessionId;
|
|
154
|
+
event.locals.authType = "cookie";
|
|
155
|
+
event.locals.user = loginEvent.locals.user;
|
|
156
|
+
status = 200;
|
|
157
|
+
try {
|
|
158
|
+
resp1 = await server.sessionServer?.userClientEndpoints.deleteClientEndpoint.load(event);
|
|
159
|
+
}
|
|
160
|
+
catch (e) {
|
|
161
|
+
if (e && typeof (e) == "object" && "status" in e && typeof (e.status) == "number")
|
|
162
|
+
status = e.status;
|
|
163
|
+
}
|
|
164
|
+
expect(status).toBe(401);
|
|
165
|
+
event = new MockRequestEvent("1", getRequest, { client_id: "bob_ABC" });
|
|
166
|
+
event.locals.csrfToken = csrfToken;
|
|
167
|
+
event.locals.sessionId = sessionId;
|
|
168
|
+
event.locals.authType = "cookie";
|
|
169
|
+
event.locals.user = loginEvent.locals.user;
|
|
170
|
+
resp1 = await server.sessionServer?.userClientEndpoints.deleteClientEndpoint.load(event);
|
|
171
|
+
expect(resp1?.ok).toBe(true);
|
|
172
|
+
let postRequest = new Request("http://ex.com/oauth/clients", {
|
|
173
|
+
method: "POST",
|
|
174
|
+
body: "csrfToken=" + csrfToken,
|
|
175
|
+
headers: [
|
|
176
|
+
["cookie", "CSRFTOKEN=" + csrfCookieValue],
|
|
177
|
+
["cookie", "SESSIONID=" + sessionCookieValue],
|
|
178
|
+
["content-type", "application/x-www-form-urlencoded"],
|
|
179
|
+
]
|
|
180
|
+
});
|
|
181
|
+
event = new MockRequestEvent("1", postRequest, { client_id: "bob_ABC" });
|
|
182
|
+
event.locals.csrfToken = csrfToken;
|
|
183
|
+
event.locals.sessionId = sessionId;
|
|
184
|
+
event.locals.authType = "cookie";
|
|
185
|
+
event.locals.user = loginEvent.locals.user;
|
|
186
|
+
resp1 = await server.sessionServer?.userClientEndpoints.deleteClientEndpoint.actions.default(event);
|
|
187
|
+
expect(resp1?.ok).toBe(true);
|
|
188
|
+
});
|
|
189
|
+
test('SvelteKitUserClientEndpoints.createClient', async () => {
|
|
190
|
+
const { server, resolver, handle } = await makeServer();
|
|
191
|
+
// log in
|
|
192
|
+
let resp = await login(server, resolver, handle);
|
|
193
|
+
let loginEvent = resp.event;
|
|
194
|
+
loginEvent = resp.event;
|
|
195
|
+
const { csrfToken, csrfCookieValue } = await getCsrfToken(server, resolver, handle);
|
|
196
|
+
let sessionCookieValue = loginEvent.cookies.get("SESSIONID");
|
|
197
|
+
let sessionId = server.sessionServer?.sessionManager.getSessionId(sessionCookieValue ?? "");
|
|
198
|
+
let getRequest = new Request("http://ex.com/oauth/clients", {
|
|
199
|
+
method: "GET",
|
|
200
|
+
headers: [
|
|
201
|
+
["cookie", "CSRFTOKEN=" + csrfCookieValue],
|
|
202
|
+
["cookie", "SESSIONID=" + sessionCookieValue],
|
|
203
|
+
["content-type", "application/x-www-form-urlencoded"],
|
|
204
|
+
]
|
|
205
|
+
});
|
|
206
|
+
let event = new MockRequestEvent("1", getRequest, {});
|
|
207
|
+
event.locals.csrfToken = csrfToken;
|
|
208
|
+
let status = 302;
|
|
209
|
+
let resp1 = {};
|
|
210
|
+
try {
|
|
211
|
+
resp1 = await server.sessionServer?.userClientEndpoints.createClientEndpoint.load(event);
|
|
212
|
+
}
|
|
213
|
+
catch (e) {
|
|
214
|
+
if (e && typeof (e) == "object" && "status" in e && typeof (e.status) == "number")
|
|
215
|
+
status = e.status;
|
|
216
|
+
}
|
|
217
|
+
expect(status).toBe(302);
|
|
218
|
+
event = new MockRequestEvent("1", getRequest, {});
|
|
219
|
+
event.locals.csrfToken = csrfToken;
|
|
220
|
+
event.locals.sessionId = sessionId;
|
|
221
|
+
event.locals.authType = "cookie";
|
|
222
|
+
event.locals.user = loginEvent.locals.user;
|
|
223
|
+
resp1 = await server.sessionServer?.userClientEndpoints.createClientEndpoint.load(event);
|
|
224
|
+
expect(resp1?.ok).toBe(true);
|
|
225
|
+
let postRequest = new Request("http://ex.com/oauth/clients", {
|
|
226
|
+
method: "POST",
|
|
227
|
+
body: "csrfToken=" + csrfToken + "&client_name=newName&confidential=on&redirect_uri=http://uri1.com/redirect&authorizationCode=on",
|
|
228
|
+
headers: [
|
|
229
|
+
["cookie", "CSRFTOKEN=" + csrfCookieValue],
|
|
230
|
+
["cookie", "SESSIONID=" + sessionCookieValue],
|
|
231
|
+
["content-type", "application/x-www-form-urlencoded"],
|
|
232
|
+
]
|
|
233
|
+
});
|
|
234
|
+
event = new MockRequestEvent("1", postRequest, { client_id: "bob_ABC" });
|
|
235
|
+
event.locals.csrfToken = csrfToken;
|
|
236
|
+
event.locals.sessionId = sessionId;
|
|
237
|
+
event.locals.authType = "cookie";
|
|
238
|
+
event.locals.user = loginEvent.locals.user;
|
|
239
|
+
resp1 = await server.sessionServer?.userClientEndpoints.createClientEndpoint.actions.default(event);
|
|
240
|
+
expect(resp1?.ok).toBe(true);
|
|
241
|
+
expect(resp1?.client?.client_name).toBe("newName");
|
|
242
|
+
expect(resp1?.plaintextSecret).toBeUndefined();
|
|
243
|
+
expect(resp1?.client?.client_secret).not.toContain("pbkdf2:sha256");
|
|
244
|
+
});
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
// Copyright (c) 2026 Matthew Baker. All rights reserved. Licenced under the Apache Licence 2.0. See LICENSE file
|
|
2
|
+
import { MockRequestEvent } from './sveltemocks';
|
|
3
|
+
import { test, expect } from 'vitest';
|
|
4
|
+
import { makeServer, getCsrfToken, login } from './testshared';
|
|
5
|
+
export var passwordResetData;
|
|
6
|
+
test('SvelteKitUserEndpoints.login', async () => {
|
|
7
|
+
const { server, resolver, handle } = await makeServer();
|
|
8
|
+
const { csrfToken, csrfCookieValue } = await getCsrfToken(server, resolver, handle);
|
|
9
|
+
const postRequest = new Request("http://ex.com/test", {
|
|
10
|
+
method: "POST",
|
|
11
|
+
body: "csrfToken=" + csrfToken + "&username=bob&password=bobPass123",
|
|
12
|
+
headers: {
|
|
13
|
+
"cookie": "CSRFTOKEN=" + csrfCookieValue,
|
|
14
|
+
"content-type": "application/x-www-form-urlencoded",
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
let event = new MockRequestEvent("1", postRequest, { "param1": "value1" });
|
|
18
|
+
event.locals.csrfToken = csrfToken;
|
|
19
|
+
const ret = await server.sessionServer?.userEndpoints.login(event);
|
|
20
|
+
expect(ret?.user?.username).toBe("bob");
|
|
21
|
+
expect(event.cookies.get("SESSIONID")).toBeDefined();
|
|
22
|
+
});
|
|
23
|
+
test('SvelteKitUserEndpoints.logout', async () => {
|
|
24
|
+
const { server, resolver, handle } = await makeServer();
|
|
25
|
+
const { csrfToken, csrfCookieValue } = await getCsrfToken(server, resolver, handle);
|
|
26
|
+
let postRequest = new Request("http://ex.com/test", {
|
|
27
|
+
method: "POST",
|
|
28
|
+
body: "csrfToken=" + csrfToken + "&username=bob&password=bobPass123",
|
|
29
|
+
headers: {
|
|
30
|
+
"cookie": "CSRFTOKEN=" + csrfCookieValue,
|
|
31
|
+
"content-type": "application/x-www-form-urlencoded",
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
let event = new MockRequestEvent("1", postRequest, { "param1": "value1" });
|
|
35
|
+
event.locals.csrfToken = csrfToken;
|
|
36
|
+
let ret = await server.sessionServer?.userEndpoints.login(event);
|
|
37
|
+
expect(ret?.user?.username).toBe("bob");
|
|
38
|
+
expect(event.cookies.get("SESSIONID")).toBeDefined();
|
|
39
|
+
postRequest = new Request("http://ex.com/test", {
|
|
40
|
+
method: "POST",
|
|
41
|
+
body: "csrfToken=" + csrfToken + "&username=bob&password=bobPass123",
|
|
42
|
+
headers: {
|
|
43
|
+
"cookie": "CSRFTOKEN=" + csrfCookieValue,
|
|
44
|
+
"content-type": "application/x-www-form-urlencoded",
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
event = new MockRequestEvent("1", postRequest, { "param1": "value1" });
|
|
48
|
+
event.locals.csrfToken = csrfToken;
|
|
49
|
+
ret = await server.sessionServer?.userEndpoints.logout(event);
|
|
50
|
+
expect(ret?.user).toBeUndefined();
|
|
51
|
+
expect(event.cookies.get("SESSIONID")).toBeUndefined();
|
|
52
|
+
});
|
|
53
|
+
test('SvelteKitUserEndpoints.resetPassword', async () => {
|
|
54
|
+
const { server, resolver, handle } = await makeServer();
|
|
55
|
+
// log in
|
|
56
|
+
await login(server, resolver, handle, "alice", "alicePass123");
|
|
57
|
+
const { csrfToken, csrfCookieValue } = await getCsrfToken(server, resolver, handle);
|
|
58
|
+
// @ts-ignore
|
|
59
|
+
server["sessionServer"]["sessionManager"]["tokenEmailer"]["_sendPasswordResetToken"] = async function (token, email, extraData) {
|
|
60
|
+
passwordResetData = { token, extraData };
|
|
61
|
+
};
|
|
62
|
+
// request password reset
|
|
63
|
+
let postRequest = new Request("http://ex.com/passwordreset", {
|
|
64
|
+
method: "POST",
|
|
65
|
+
body: "csrfToken=" + csrfToken + "&email=bob@bob.com",
|
|
66
|
+
headers: {
|
|
67
|
+
"cookie": "CSRFTOKEN=" + csrfCookieValue,
|
|
68
|
+
"content-type": "application/x-www-form-urlencoded",
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
let event = new MockRequestEvent("1", postRequest, {});
|
|
72
|
+
event.locals.csrfToken = csrfToken;
|
|
73
|
+
event.cookies.set("CSRFTOKEN", csrfCookieValue, { path: "/" });
|
|
74
|
+
let resp1 = await server.sessionServer?.userEndpoints.requestPasswordReset(event);
|
|
75
|
+
expect(resp1?.ok).toBe(true);
|
|
76
|
+
const token = passwordResetData.token;
|
|
77
|
+
// submit password reset
|
|
78
|
+
postRequest = new Request("http://ex.com/passwordreset/" + token, {
|
|
79
|
+
method: "POST",
|
|
80
|
+
body: "csrfToken=" + csrfToken + "&new_password='ABCabc123'&repeat_password='ABCabc123'",
|
|
81
|
+
headers: {
|
|
82
|
+
"cookie": "CSRFTOKEN=" + csrfCookieValue,
|
|
83
|
+
"content-type": "application/x-www-form-urlencoded",
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
event = new MockRequestEvent("1", postRequest, { token: token });
|
|
87
|
+
event.locals.csrfToken = csrfToken;
|
|
88
|
+
event.cookies.set("CSRFTOKEN", csrfCookieValue, { path: "/" });
|
|
89
|
+
resp1 = await server.sessionServer?.userEndpoints.resetPassword(event);
|
|
90
|
+
expect(resp1?.ok).toBe(true);
|
|
91
|
+
});
|
|
92
|
+
test('SvelteKitUserEndpoints.changePassword', async () => {
|
|
93
|
+
const { server, resolver, handle } = await makeServer();
|
|
94
|
+
// log in
|
|
95
|
+
let resp = await login(server, resolver, handle, "bob", "bobPass123");
|
|
96
|
+
let loginEvent = resp.event;
|
|
97
|
+
loginEvent = resp.event;
|
|
98
|
+
const { csrfToken, csrfCookieValue } = await getCsrfToken(server, resolver, handle);
|
|
99
|
+
let sessionCookieValue = loginEvent.cookies.get("SESSIONID");
|
|
100
|
+
let sessionId = server.sessionServer?.sessionManager.getSessionId(sessionCookieValue ?? "");
|
|
101
|
+
// change password
|
|
102
|
+
let postRequest = new Request("http://ex.com/changepassword", {
|
|
103
|
+
method: "POST",
|
|
104
|
+
body: "csrfToken=" + csrfToken + "&old_password=bobPass123&new_password=bobPass12&repeat_password=bobPass12",
|
|
105
|
+
headers: [
|
|
106
|
+
["cookie", "CSRFTOKEN=" + csrfCookieValue],
|
|
107
|
+
["cookie", "SESSIONID=" + sessionCookieValue],
|
|
108
|
+
["content-type", "application/x-www-form-urlencoded"],
|
|
109
|
+
]
|
|
110
|
+
});
|
|
111
|
+
let event = new MockRequestEvent("1", postRequest, {});
|
|
112
|
+
event.locals.csrfToken = csrfToken;
|
|
113
|
+
event.locals.sessionId = sessionId;
|
|
114
|
+
event.locals.authType = "cookie";
|
|
115
|
+
event.locals.user = loginEvent.locals.user;
|
|
116
|
+
let resp1 = await server.sessionServer?.userEndpoints.changePassword(event);
|
|
117
|
+
expect(resp1?.ok).toBe(true);
|
|
118
|
+
});
|
|
119
|
+
test('SvelteKitUserEndpoints.deleteUser', async () => {
|
|
120
|
+
const { server, resolver, handle, userStorage } = await makeServer();
|
|
121
|
+
// log in
|
|
122
|
+
let resp = await login(server, resolver, handle, "bob", "bobPass123");
|
|
123
|
+
let loginEvent = resp.event;
|
|
124
|
+
loginEvent = resp.event;
|
|
125
|
+
const { csrfToken, csrfCookieValue } = await getCsrfToken(server, resolver, handle);
|
|
126
|
+
let sessionCookieValue = loginEvent.cookies.get("SESSIONID");
|
|
127
|
+
let sessionId = server.sessionServer?.sessionManager.getSessionId(sessionCookieValue ?? "");
|
|
128
|
+
// delete user
|
|
129
|
+
let postRequest = new Request("http://ex.com/deleteuser", {
|
|
130
|
+
method: "POST",
|
|
131
|
+
body: "csrfToken=" + csrfToken,
|
|
132
|
+
headers: [
|
|
133
|
+
["cookie", "CSRFTOKEN=" + csrfCookieValue],
|
|
134
|
+
["cookie", "SESSIONID=" + sessionCookieValue],
|
|
135
|
+
["content-type", "application/x-www-form-urlencoded"],
|
|
136
|
+
]
|
|
137
|
+
});
|
|
138
|
+
let event = new MockRequestEvent("1", postRequest, {});
|
|
139
|
+
event.locals.csrfToken = csrfToken;
|
|
140
|
+
event.locals.sessionId = sessionId;
|
|
141
|
+
event.locals.authType = "cookie";
|
|
142
|
+
event.locals.user = loginEvent.locals.user;
|
|
143
|
+
let resp1 = await server.sessionServer?.userEndpoints.deleteUser(event);
|
|
144
|
+
expect(resp1?.ok).toBe(true);
|
|
145
|
+
let found = false;
|
|
146
|
+
try {
|
|
147
|
+
await userStorage.getUserByUsername("bob");
|
|
148
|
+
found = true;
|
|
149
|
+
}
|
|
150
|
+
catch (e) { }
|
|
151
|
+
expect(found).toBe(false);
|
|
152
|
+
});
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// Copyright (c) 2026 Matthew Baker. All rights reserved. Licenced under the Apache Licence 2.0. See LICENSE file
|
|
2
|
+
import { MockRequestEvent, MockCookies } from './sveltemocks';
|
|
3
|
+
import { test, expect } from 'vitest';
|
|
4
|
+
test('SvelteMocks.Request', async () => {
|
|
5
|
+
const request = new Request("http://ex.com/test", { method: "POST", body: "This is the body" });
|
|
6
|
+
expect(request.body).not.toBe(null);
|
|
7
|
+
if (request.body)
|
|
8
|
+
expect(await (new Response(request.body).text())).toBe("This is the body");
|
|
9
|
+
});
|
|
10
|
+
test('SvelteMocks.MockRequestEvent', async () => {
|
|
11
|
+
const request = new Request("http://ex.com/test", { method: "POST", body: "This is the body" });
|
|
12
|
+
const requestEvent = new MockRequestEvent("1", request, { "param1": "value1" });
|
|
13
|
+
expect(requestEvent.route.id).toBe("1");
|
|
14
|
+
expect(requestEvent.params["param1"]).toBe("value1");
|
|
15
|
+
});
|
|
16
|
+
test('SvelteMocks.MockCookies', async () => {
|
|
17
|
+
const cookies = new MockCookies({
|
|
18
|
+
"cookie1": { value: "value1", opts: { maxAge: 120, domain: "http://example1.com" } },
|
|
19
|
+
"cookie2": { value: "value&2", opts: { maxAge: 140, domain: "http://example2.com" } },
|
|
20
|
+
});
|
|
21
|
+
// get cookie
|
|
22
|
+
let value1 = await cookies.get("cookie1");
|
|
23
|
+
expect(value1).toBe("value1");
|
|
24
|
+
let value2 = await cookies.get("cookie2");
|
|
25
|
+
expect(value2).toBe("value&2");
|
|
26
|
+
// get all
|
|
27
|
+
let values = await cookies.getAll();
|
|
28
|
+
expect(values.length).toBe(2);
|
|
29
|
+
// set cookie
|
|
30
|
+
await cookies.set("cookie1", "value3", { maxAge: 120, domain: "http://example3.com", path: "/" });
|
|
31
|
+
value1 = await cookies.get("cookie1");
|
|
32
|
+
expect(value1).toBe("value3");
|
|
33
|
+
await cookies.delete("cookie1", { path: "/" });
|
|
34
|
+
value1 = await cookies.get("cookie1");
|
|
35
|
+
expect(value1).toBe(undefined);
|
|
36
|
+
});
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { Cookies, ResolveOptions } from '@sveltejs/kit';
|
|
2
|
-
import { CookieParseOptions, CookieSerializeOptions } from 'cookie';
|
|
3
|
-
|
|
1
|
+
import { type Cookies, type ResolveOptions } from '@sveltejs/kit';
|
|
2
|
+
import { type CookieParseOptions, type CookieSerializeOptions } from 'cookie';
|
|
4
3
|
export interface AppTypes {
|
|
5
4
|
RouteId(): string;
|
|
6
5
|
RouteParams(): Record<string, Record<string, string>>;
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
// Copyright (c) 2026 Matthew Baker. All rights reserved. Licenced under the Apache Licence 2.0. See LICENSE file
|
|
2
|
+
import {} from '@sveltejs/kit';
|
|
3
|
+
import cookie, {} from 'cookie';
|
|
4
|
+
export class MockCookies {
|
|
5
|
+
cookies;
|
|
6
|
+
constructor(cookies, req) {
|
|
7
|
+
this.cookies = cookies;
|
|
8
|
+
if (req) {
|
|
9
|
+
const reqCookiesString = req.headers.get("cookie");
|
|
10
|
+
if (reqCookiesString) {
|
|
11
|
+
const reqCookies = reqCookiesString.split(";");
|
|
12
|
+
for (let reqCookie of reqCookies) {
|
|
13
|
+
const pair = reqCookie.trim().split("=", 2);
|
|
14
|
+
if (pair.length == 2) {
|
|
15
|
+
const name = decodeURIComponent(pair[0]);
|
|
16
|
+
const value = decodeURIComponent(pair[1]);
|
|
17
|
+
this.cookies[name] = { value: value };
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
get(name, opts) {
|
|
24
|
+
// opts is ignored on the assumption
|
|
25
|
+
const decoder = opts?.decode ?? "decodeURIComponent";
|
|
26
|
+
if (name in this.cookies)
|
|
27
|
+
return eval(decoder + "('" + this.cookies[name].value + "')");
|
|
28
|
+
return undefined;
|
|
29
|
+
}
|
|
30
|
+
getAll(opts) {
|
|
31
|
+
const decoder = opts?.decode ?? "decodeURIComponent";
|
|
32
|
+
let ret = [];
|
|
33
|
+
for (let name in this.cookies)
|
|
34
|
+
ret.push({ name: name, value: eval(decoder + "('" + this.cookies[name].value + "')") });
|
|
35
|
+
return ret;
|
|
36
|
+
}
|
|
37
|
+
set(name, value, opts) {
|
|
38
|
+
this.cookies[name] = { value, opts };
|
|
39
|
+
}
|
|
40
|
+
delete(name, _opts) {
|
|
41
|
+
if (name in this.cookies)
|
|
42
|
+
delete this.cookies[name];
|
|
43
|
+
}
|
|
44
|
+
serialize(name, value, opts) {
|
|
45
|
+
return cookie.serialize(name, value, opts);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
export class MockRequestEvent {
|
|
49
|
+
constructor(id, request, params, { isDataRequest = false, isSubRequest = false, cookies = {}, baseUrl = "http://example.com" } = {}) {
|
|
50
|
+
this.cookies = new MockCookies(cookies, request);
|
|
51
|
+
this.fetch = fetch;
|
|
52
|
+
this.locals = { authType: undefined };
|
|
53
|
+
this.params = params;
|
|
54
|
+
this.request = request;
|
|
55
|
+
try {
|
|
56
|
+
this.url = new URL(request.url);
|
|
57
|
+
}
|
|
58
|
+
catch (e) {
|
|
59
|
+
this.url = new URL(request.url, baseUrl);
|
|
60
|
+
}
|
|
61
|
+
this.isDataRequest = isDataRequest;
|
|
62
|
+
this.isSubRequest = isSubRequest;
|
|
63
|
+
this.route = { id: id };
|
|
64
|
+
this.tracing = { enabled: false, root: "", current: "" };
|
|
65
|
+
this.isRemoteRequest = false;
|
|
66
|
+
}
|
|
67
|
+
cookies;
|
|
68
|
+
fetch;
|
|
69
|
+
getClientAddress() {
|
|
70
|
+
throw new Error('Method not implemented.');
|
|
71
|
+
}
|
|
72
|
+
locals;
|
|
73
|
+
params;
|
|
74
|
+
platform;
|
|
75
|
+
request;
|
|
76
|
+
route;
|
|
77
|
+
headers = undefined;
|
|
78
|
+
setHeaders(headers) {
|
|
79
|
+
this.headers = headers;
|
|
80
|
+
}
|
|
81
|
+
url;
|
|
82
|
+
isDataRequest;
|
|
83
|
+
isSubRequest;
|
|
84
|
+
tracing;
|
|
85
|
+
isRemoteRequest;
|
|
86
|
+
}
|
|
87
|
+
export class MockResolver {
|
|
88
|
+
body;
|
|
89
|
+
status;
|
|
90
|
+
statusText;
|
|
91
|
+
constructor(body, status = 200, statusText = "OK") {
|
|
92
|
+
this.body = body;
|
|
93
|
+
this.status = status;
|
|
94
|
+
this.statusText = statusText;
|
|
95
|
+
this.mockResolve = (event, _opts) => {
|
|
96
|
+
let headers = [];
|
|
97
|
+
for (let header in event.headers) {
|
|
98
|
+
headers.push([header, event.headers[header]]);
|
|
99
|
+
}
|
|
100
|
+
let cookies = event.cookies.getAll();
|
|
101
|
+
if (cookies && cookies.length > 0) {
|
|
102
|
+
for (let cookie of cookies) {
|
|
103
|
+
headers.push(["set-cookie", cookie.name + "=" + cookie.value]);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return new Response(this.body, {
|
|
107
|
+
headers: headers,
|
|
108
|
+
status: this.status ?? 200,
|
|
109
|
+
statusText: this.statusText ?? "OK",
|
|
110
|
+
});
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
mockResolve;
|
|
114
|
+
}
|