sporades 0.7.1 โ 0.7.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/CHANGES.md +3 -16
- package/bin/sporades-host-helper.js +1 -1
- package/bin/sporades.js +37 -14
- package/dist/auth-runtime.d.ts +2 -1
- package/dist/auth-runtime.d.ts.map +1 -1
- package/dist/auth-runtime.js +25 -7
- package/dist/auth-runtime.js.map +1 -1
- package/dist/cli/cli-version.d.ts +1 -1
- package/dist/cli/cli-version.js +1 -1
- package/dist/server-runtime-source.d.ts.map +1 -1
- package/dist/server-runtime-source.js +1 -1
- package/dist/server-runtime-source.js.map +1 -1
- package/dist/templates/client-runtime-template.js +11 -11
- package/package.json +1 -1
- package/src/types/client.d.ts +2 -1
package/CHANGES.md
CHANGED
|
@@ -1,22 +1,9 @@
|
|
|
1
1
|
# Changes
|
|
2
2
|
|
|
3
|
-
## Unreleased - 2026-08-
|
|
3
|
+
## Unreleased - 2026-08-13
|
|
4
4
|
|
|
5
|
-
Changes since v0.7.
|
|
6
|
-
|
|
7
|
-
### ๐ Features
|
|
8
|
-
|
|
9
|
-
- Adapt Mailgun email events (66d4291).
|
|
10
|
-
- Adapt Postmark email events (d30efa2).
|
|
11
|
-
- Adapt SMTP2GO email events (8d39237).
|
|
12
|
-
- Dispatch verified email provider events (d818b6d).
|
|
13
|
-
- Trust required native installers (c0a539c).
|
|
5
|
+
Changes since v0.7.1.
|
|
14
6
|
|
|
15
7
|
### ๐ Documentation
|
|
16
8
|
|
|
17
|
-
-
|
|
18
|
-
- Document Mailjet SMTP configuration (e710ba2).
|
|
19
|
-
|
|
20
|
-
### ๐งช Tests
|
|
21
|
-
|
|
22
|
-
- Cover Mailgun non-delivery retries (c5e566e).
|
|
9
|
+
- Require current password to change email credentials (bfba651).
|
|
@@ -413,7 +413,7 @@ function writeEnvelope(result, failed = false) {
|
|
|
413
413
|
}
|
|
414
414
|
|
|
415
415
|
// src/cli/cli-version.ts
|
|
416
|
-
var CLI_VERSION = "0.7.
|
|
416
|
+
var CLI_VERSION = "0.7.2";
|
|
417
417
|
|
|
418
418
|
// src/cli/schedule-inspection-envelope.ts
|
|
419
419
|
function sanitizeScheduleInspectionEnvelope(envelope, invalid) {
|
package/bin/sporades.js
CHANGED
|
@@ -82,8 +82,8 @@ export const auth = {
|
|
|
82
82
|
signOut() {
|
|
83
83
|
return connect().signOut();
|
|
84
84
|
},
|
|
85
|
-
setPassword(email, newPassword) {
|
|
86
|
-
return connect().setPassword(email, newPassword);
|
|
85
|
+
setPassword(email, currentPassword, newPassword) {
|
|
86
|
+
return connect().setPassword(email, currentPassword, newPassword);
|
|
87
87
|
},
|
|
88
88
|
sendPasswordResetLink(email) {
|
|
89
89
|
return connect().sendPasswordResetLink(email);
|
|
@@ -174,8 +174,8 @@ export function createHooks(primitives) {
|
|
|
174
174
|
signOut() {
|
|
175
175
|
return connect().signOut();
|
|
176
176
|
},
|
|
177
|
-
setPassword(email, newPassword) {
|
|
178
|
-
return connect().setPassword(email, newPassword);
|
|
177
|
+
setPassword(email, currentPassword, newPassword) {
|
|
178
|
+
return connect().setPassword(email, currentPassword, newPassword);
|
|
179
179
|
},
|
|
180
180
|
};
|
|
181
181
|
}
|
|
@@ -232,7 +232,7 @@ export function createVueComposables(primitives) {
|
|
|
232
232
|
state.signUp = (provider, credentials) => connect().signUp(provider, credentials);
|
|
233
233
|
state.signIn = (provider, credentials) => connect().signIn(provider, credentials);
|
|
234
234
|
state.signOut = () => connect().signOut();
|
|
235
|
-
state.setPassword = (email, newPassword) => connect().setPassword(email, newPassword);
|
|
235
|
+
state.setPassword = (email, currentPassword, newPassword) => connect().setPassword(email, currentPassword, newPassword);
|
|
236
236
|
return state;
|
|
237
237
|
}
|
|
238
238
|
|
|
@@ -284,7 +284,7 @@ export function createSolidPrimitives(primitives) {
|
|
|
284
284
|
signUp: (provider, credentials) => connect().signUp(provider, credentials),
|
|
285
285
|
signIn: (provider, credentials) => connect().signIn(provider, credentials),
|
|
286
286
|
signOut: () => connect().signOut(),
|
|
287
|
-
setPassword: (email, newPassword) => connect().setPassword(email, newPassword),
|
|
287
|
+
setPassword: (email, currentPassword, newPassword) => connect().setPassword(email, currentPassword, newPassword),
|
|
288
288
|
};
|
|
289
289
|
}
|
|
290
290
|
|
|
@@ -382,7 +382,7 @@ export function createLitControllers() {
|
|
|
382
382
|
controller.signUp = (provider, credentials) => connect().signUp(provider, credentials);
|
|
383
383
|
controller.signIn = (provider, credentials) => connect().signIn(provider, credentials);
|
|
384
384
|
controller.signOut = () => connect().signOut();
|
|
385
|
-
controller.setPassword = (email, newPassword) => connect().setPassword(email, newPassword);
|
|
385
|
+
controller.setPassword = (email, currentPassword, newPassword) => connect().setPassword(email, currentPassword, newPassword);
|
|
386
386
|
return controller;
|
|
387
387
|
}
|
|
388
388
|
|
|
@@ -455,7 +455,7 @@ export function createInfernoAdapters() {
|
|
|
455
455
|
adapter.signUp = (provider, credentials) => connect().signUp(provider, credentials);
|
|
456
456
|
adapter.signIn = (provider, credentials) => connect().signIn(provider, credentials);
|
|
457
457
|
adapter.signOut = () => connect().signOut();
|
|
458
|
-
adapter.setPassword = (email, newPassword) => connect().setPassword(email, newPassword);
|
|
458
|
+
adapter.setPassword = (email, currentPassword, newPassword) => connect().setPassword(email, currentPassword, newPassword);
|
|
459
459
|
return adapter;
|
|
460
460
|
}
|
|
461
461
|
return { queryAdapter, mutationAdapter, authAdapter };
|
|
@@ -505,7 +505,7 @@ export function createSvelteStores() {
|
|
|
505
505
|
signUp: (provider, credentials) => connect().signUp(provider, credentials),
|
|
506
506
|
signIn: (provider, credentials) => connect().signIn(provider, credentials),
|
|
507
507
|
signOut: () => connect().signOut(),
|
|
508
|
-
setPassword: (email, newPassword) => connect().setPassword(email, newPassword),
|
|
508
|
+
setPassword: (email, currentPassword, newPassword) => connect().setPassword(email, currentPassword, newPassword),
|
|
509
509
|
};
|
|
510
510
|
}
|
|
511
511
|
|
|
@@ -1010,8 +1010,8 @@ function createConnection() {
|
|
|
1010
1010
|
return result;
|
|
1011
1011
|
});
|
|
1012
1012
|
},
|
|
1013
|
-
setPassword(email, newPassword) {
|
|
1014
|
-
return request("auth.setPassword", { email, newPassword });
|
|
1013
|
+
setPassword(email, currentPassword, newPassword) {
|
|
1014
|
+
return request("auth.setPassword", { email, currentPassword, newPassword });
|
|
1015
1015
|
},
|
|
1016
1016
|
sendPasswordResetLink(email) {
|
|
1017
1017
|
return request("auth.sendPasswordResetLink", { email });
|
|
@@ -7053,6 +7053,7 @@ var EMAIL_SIGN_IN_FAILURE_LIMIT = 5;
|
|
|
7053
7053
|
var EMAIL_SIGN_IN_THROTTLE_WINDOW_MS = 15 * 60 * 1e3;
|
|
7054
7054
|
var EMAIL_SIGN_IN_THROTTLE_MAX_ENTRIES = 256;
|
|
7055
7055
|
var EMAIL_SIGN_IN_THROTTLE_FIELD = "__emailSignInThrottle";
|
|
7056
|
+
var PASSWORD_CHANGE_THROTTLE_FIELD = "__emailPasswordChangeThrottle";
|
|
7056
7057
|
var PASSWORD_RESET_THROTTLE_FIELD = "__emailPasswordResetThrottle";
|
|
7057
7058
|
var PASSWORD_RESET_DEFAULT_PATH = "/reset-password";
|
|
7058
7059
|
var PASSWORD_RESET_DEFAULT_TTL_MS = 60 * 60 * 1e3;
|
|
@@ -8827,7 +8828,7 @@ function mailNotConfiguredError() {
|
|
|
8827
8828
|
hint: "Set `mail.smtp` in sporades.json, or use ctx.serverAuth.createEmailPasswordResetLink with your own delivery path."
|
|
8828
8829
|
};
|
|
8829
8830
|
}
|
|
8830
|
-
async function setOwnEmailPassword(database, session, email, newPassword) {
|
|
8831
|
+
async function setOwnEmailPassword(database, session, email, currentPassword, newPassword) {
|
|
8831
8832
|
let auth;
|
|
8832
8833
|
try {
|
|
8833
8834
|
auth = requireAuth({ ...session, kind: "message" }, { linked: true });
|
|
@@ -8839,6 +8840,15 @@ async function setOwnEmailPassword(database, session, email, newPassword) {
|
|
|
8839
8840
|
if (!credential || credential.userId !== auth.userId) {
|
|
8840
8841
|
return { ok: false, error: emailNotOwnedError() };
|
|
8841
8842
|
}
|
|
8843
|
+
const throttle = currentEmailSignInThrottleState(database, cleanEmail, session, PASSWORD_CHANGE_THROTTLE_FIELD);
|
|
8844
|
+
if (throttle.throttled) {
|
|
8845
|
+
return { ok: false, error: invalidCurrentPasswordError() };
|
|
8846
|
+
}
|
|
8847
|
+
if (typeof currentPassword !== "string" || !verifyEmailPassword(currentPassword, credential.passwordSalt, credential.passwordHash)) {
|
|
8848
|
+
recordFailedEmailSignInAttempt(database, cleanEmail, session, PASSWORD_CHANGE_THROTTLE_FIELD);
|
|
8849
|
+
return { ok: false, error: invalidCurrentPasswordError() };
|
|
8850
|
+
}
|
|
8851
|
+
resetEmailSignInAttempts(database, cleanEmail, session, PASSWORD_CHANGE_THROTTLE_FIELD);
|
|
8842
8852
|
return await setEmailPassword(database, session, cleanEmail, newPassword);
|
|
8843
8853
|
}
|
|
8844
8854
|
function emailNotOwnedError() {
|
|
@@ -8848,6 +8858,13 @@ function emailNotOwnedError() {
|
|
|
8848
8858
|
hint: "Change the password for the signed-in account, or use a password reset link."
|
|
8849
8859
|
};
|
|
8850
8860
|
}
|
|
8861
|
+
function invalidCurrentPasswordError() {
|
|
8862
|
+
return {
|
|
8863
|
+
code: "INVALID_CURRENT_PASSWORD",
|
|
8864
|
+
message: "Current password is incorrect.",
|
|
8865
|
+
hint: "Enter the current password for this email credential, or use a password reset link."
|
|
8866
|
+
};
|
|
8867
|
+
}
|
|
8851
8868
|
async function setEmailPassword(database, _session, email, newPassword) {
|
|
8852
8869
|
if (!database.authConfig.providers.email.enabled) {
|
|
8853
8870
|
return { ok: false, error: emailAuthDisabledError() };
|
|
@@ -15161,7 +15178,13 @@ function createWebSocketHub(getDatabase, trustedRefresh = null) {
|
|
|
15161
15178
|
return;
|
|
15162
15179
|
}
|
|
15163
15180
|
if (message.type === "auth.setPassword") {
|
|
15164
|
-
const result = await setOwnEmailPassword(
|
|
15181
|
+
const result = await setOwnEmailPassword(
|
|
15182
|
+
database,
|
|
15183
|
+
client.session,
|
|
15184
|
+
message.email ?? "",
|
|
15185
|
+
message.currentPassword ?? "",
|
|
15186
|
+
message.newPassword ?? ""
|
|
15187
|
+
);
|
|
15165
15188
|
sendJson(client, {
|
|
15166
15189
|
id: message.id ?? null,
|
|
15167
15190
|
type: result.ok ? "auth.setPassword.result" : "error",
|
|
@@ -22142,7 +22165,7 @@ jobs:
|
|
|
22142
22165
|
}
|
|
22143
22166
|
|
|
22144
22167
|
// src/cli/cli-version.ts
|
|
22145
|
-
var CLI_VERSION = "0.7.
|
|
22168
|
+
var CLI_VERSION = "0.7.2";
|
|
22146
22169
|
|
|
22147
22170
|
// src/cli/sporades.ts
|
|
22148
22171
|
var SUPPORTED_TEMPLATES = new Set(CLIENT_TEMPLATES);
|
package/dist/auth-runtime.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ export declare const EMAIL_SIGN_IN_FAILURE_LIMIT = 5;
|
|
|
7
7
|
export declare const EMAIL_SIGN_IN_THROTTLE_WINDOW_MS: number;
|
|
8
8
|
export declare const EMAIL_SIGN_IN_THROTTLE_MAX_ENTRIES = 256;
|
|
9
9
|
export declare const EMAIL_SIGN_IN_THROTTLE_FIELD = "__emailSignInThrottle";
|
|
10
|
+
export declare const PASSWORD_CHANGE_THROTTLE_FIELD = "__emailPasswordChangeThrottle";
|
|
10
11
|
export declare const PASSWORD_RESET_THROTTLE_FIELD = "__emailPasswordResetThrottle";
|
|
11
12
|
export declare const PASSWORD_RESET_DEFAULT_PATH = "/reset-password";
|
|
12
13
|
export declare const PASSWORD_RESET_DEFAULT_TTL_MS: number;
|
|
@@ -135,7 +136,7 @@ export declare function mailNotConfiguredError(): {
|
|
|
135
136
|
message: string;
|
|
136
137
|
hint: string;
|
|
137
138
|
};
|
|
138
|
-
export declare function setOwnEmailPassword(database: LooseRecord, session: LooseRecord, email: string, newPassword: string): Promise<{
|
|
139
|
+
export declare function setOwnEmailPassword(database: LooseRecord, session: LooseRecord, email: string, currentPassword: string, newPassword: string): Promise<{
|
|
139
140
|
ok: boolean;
|
|
140
141
|
error: {
|
|
141
142
|
message: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth-runtime.d.ts","sourceRoot":"","sources":["../src/auth-runtime.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"auth-runtime.d.ts","sourceRoot":"","sources":["../src/auth-runtime.ts"],"names":[],"mappings":"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"}
|
package/dist/auth-runtime.js
CHANGED
|
@@ -108,6 +108,7 @@ export const EMAIL_SIGN_IN_FAILURE_LIMIT = 5;
|
|
|
108
108
|
export const EMAIL_SIGN_IN_THROTTLE_WINDOW_MS = 15 * 60 * 1000;
|
|
109
109
|
export const EMAIL_SIGN_IN_THROTTLE_MAX_ENTRIES = 256;
|
|
110
110
|
export const EMAIL_SIGN_IN_THROTTLE_FIELD = "__emailSignInThrottle";
|
|
111
|
+
export const PASSWORD_CHANGE_THROTTLE_FIELD = "__emailPasswordChangeThrottle";
|
|
111
112
|
export const PASSWORD_RESET_THROTTLE_FIELD = "__emailPasswordResetThrottle";
|
|
112
113
|
export const PASSWORD_RESET_DEFAULT_PATH = "/reset-password";
|
|
113
114
|
export const PASSWORD_RESET_DEFAULT_TTL_MS = 60 * 60 * 1000;
|
|
@@ -1968,11 +1969,12 @@ export function mailNotConfiguredError() {
|
|
|
1968
1969
|
};
|
|
1969
1970
|
}
|
|
1970
1971
|
// Browser-facing password change. `setEmailPassword` is the trusted server-only
|
|
1971
|
-
// API and deliberately accepts any registered email, so the ownership
|
|
1972
|
-
// here rather than there: a browser may only
|
|
1973
|
-
//
|
|
1974
|
-
//
|
|
1975
|
-
|
|
1972
|
+
// API and deliberately accepts any registered email, so the ownership and
|
|
1973
|
+
// re-authentication gates live here rather than there: a browser may only
|
|
1974
|
+
// change the credential its own Session owns after proving knowledge of its
|
|
1975
|
+
// current password. Non-existent and someone-else's emails share one opaque
|
|
1976
|
+
// denial, so this cannot be used to discover which addresses have accounts.
|
|
1977
|
+
export async function setOwnEmailPassword(database, session, email, currentPassword, newPassword) {
|
|
1976
1978
|
let auth;
|
|
1977
1979
|
try {
|
|
1978
1980
|
auth = requireAuth({ ...session, kind: "message" }, { linked: true });
|
|
@@ -1985,6 +1987,15 @@ export async function setOwnEmailPassword(database, session, email, newPassword)
|
|
|
1985
1987
|
if (!credential || credential.userId !== auth.userId) {
|
|
1986
1988
|
return { ok: false, error: emailNotOwnedError() };
|
|
1987
1989
|
}
|
|
1990
|
+
const throttle = currentEmailSignInThrottleState(database, cleanEmail, session, PASSWORD_CHANGE_THROTTLE_FIELD);
|
|
1991
|
+
if (throttle.throttled) {
|
|
1992
|
+
return { ok: false, error: invalidCurrentPasswordError() };
|
|
1993
|
+
}
|
|
1994
|
+
if (typeof currentPassword !== "string" || !verifyEmailPassword(currentPassword, credential.passwordSalt, credential.passwordHash)) {
|
|
1995
|
+
recordFailedEmailSignInAttempt(database, cleanEmail, session, PASSWORD_CHANGE_THROTTLE_FIELD);
|
|
1996
|
+
return { ok: false, error: invalidCurrentPasswordError() };
|
|
1997
|
+
}
|
|
1998
|
+
resetEmailSignInAttempts(database, cleanEmail, session, PASSWORD_CHANGE_THROTTLE_FIELD);
|
|
1988
1999
|
return await setEmailPassword(database, session, cleanEmail, newPassword);
|
|
1989
2000
|
}
|
|
1990
2001
|
function emailNotOwnedError() {
|
|
@@ -1994,6 +2005,13 @@ function emailNotOwnedError() {
|
|
|
1994
2005
|
hint: "Change the password for the signed-in account, or use a password reset link.",
|
|
1995
2006
|
};
|
|
1996
2007
|
}
|
|
2008
|
+
function invalidCurrentPasswordError() {
|
|
2009
|
+
return {
|
|
2010
|
+
code: "INVALID_CURRENT_PASSWORD",
|
|
2011
|
+
message: "Current password is incorrect.",
|
|
2012
|
+
hint: "Enter the current password for this email credential, or use a password reset link.",
|
|
2013
|
+
};
|
|
2014
|
+
}
|
|
1997
2015
|
export async function setEmailPassword(database, _session, email, newPassword) {
|
|
1998
2016
|
if (!database.authConfig.providers.email.enabled) {
|
|
1999
2017
|
return { ok: false, error: emailAuthDisabledError() };
|
|
@@ -2013,8 +2031,8 @@ export async function setEmailPassword(database, _session, email, newPassword) {
|
|
|
2013
2031
|
await database.adapter.updateEmailCredentialPassword(cleanEmail, password.hash, password.salt);
|
|
2014
2032
|
return { ok: true };
|
|
2015
2033
|
}
|
|
2016
|
-
// Sign-in
|
|
2017
|
-
// bucket:
|
|
2034
|
+
// Sign-in, password-change, and reset requests share this throttle shape but
|
|
2035
|
+
// never share a bucket: one auth action must not lock out another.
|
|
2018
2036
|
function createEmailSignInThrottleState(database, scope = EMAIL_SIGN_IN_THROTTLE_FIELD) {
|
|
2019
2037
|
const existing = database[scope];
|
|
2020
2038
|
if (existing instanceof Map) {
|