fix(events): publish-from-draft email carries the real password (#627)
Previously, publishing a password-protected DRAFT gallery sent the gallery_created email with the literal sentinel "(set at creation)", which the email processor localised to "The password you set when creating the gallery" / "Das bei der Erstellung der Galerie gesetzte Passwort". Root cause: at draft creation only the bcrypt hash is stored (no plaintext column, by design); the publish endpoint had nowhere to pull the actual password from. Create-and-publish-in-one-step worked because the plaintext is still in memory at email-queue time. Fix: the Publish action now opens a small PublishGalleryDialog that prompts the admin to (re-)type the gallery password. The publish endpoint accepts an optional `password` body, re-hashes + writes `password_hash` so the stored hash matches what was just emailed (admins who mistype at creation get a self-healing publish flow), and puts the plaintext into the gallery_password email field. When the publish call is made without a password (API-only consumers), behaviour falls back to the legacy sentinel — no breaking change. The window.confirm() publish flow is gone; the dialog handles the no- password case too (plain confirm + Publish button). I18n: EN + DE entries for the dialog. Other locales fall through to the EN defaults via the t() default-value pattern. No schema changes. No plaintext at rest.
This commit is contained in:
@@ -219,9 +219,16 @@ export const eventsService = {
|
||||
return response.data;
|
||||
},
|
||||
|
||||
// Publish a draft event
|
||||
async publishEvent(eventId: number): Promise<{ message: string; is_draft: boolean }> {
|
||||
const response = await api.post(`/admin/events/${eventId}/publish`);
|
||||
// Publish a draft event. `password` is optional; when the event is
|
||||
// password-protected, supplying the password here makes the gallery_created
|
||||
// email carry the actual plaintext instead of the "set at creation" sentinel
|
||||
// (#627) — the backend also re-hashes it so the stored hash matches.
|
||||
async publishEvent(
|
||||
eventId: number,
|
||||
options?: { password?: string },
|
||||
): Promise<{ message: string; is_draft: boolean }> {
|
||||
const body = options?.password ? { password: options.password } : undefined;
|
||||
const response = await api.post(`/admin/events/${eventId}/publish`, body);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
|
||||
Reference in New Issue
Block a user