feat: implement permissions and actions management
CI / Lint, typecheck, test, build (push) Canceled after 0s
CI / End-to-end tests (push) Canceled after 0s

- Add permissions logic for status options in corrective actions.
- Create tests for permissions functionality.
- Implement queries for user authentication and actions management.
- Develop Actions page to display and manage corrective actions.
- Create authentication pages for login, setup, and password reset.
- Add IncidentDetail page to view incident details and associated actions.
- Implement Settings page for user management and password changes.
This commit is contained in:
jayjennings committed 2026-10-06 11:20:44 -07:00
1 parent 708da6b9f7
commit 3f6dff5f24
94 files changed
+7213 -643

No files matched your search

+39
View File
@@ -0,0 +1,39 @@
import nodemailer from 'nodemailer'
import type { Config } from './config.ts'
export interface Mail {
to: string
subject: string
text: string
}
export interface Mailer {
send(mail: Mail): Promise<void>
}
export function createMailer(config: Config): Mailer {
if (config.smtpUrl) {
const transport = nodemailer.createTransport(config.smtpUrl)
return { send: async (mail) => void (await transport.sendMail({ from: config.mailFrom, ...mail })) }
}
if (config.production) {
console.warn('[mail] SMTP_URL is not set: emails (sign-in links, password resets, notifications) will not be sent.')
return { send: async (mail) => console.warn(`[mail] Not sent (no SMTP): "${mail.subject}" to ${mail.to}`) }
}
// Development: print the email so links can be clicked from the terminal.
return { send: async (mail) => console.log(`\n[mail] To: ${mail.to}\n[mail] Subject: ${mail.subject}\n\n${mail.text}\n`) }
}
/** Collects emails instead of sending them (tests). */
export class MemoryMailer implements Mailer {
sent: Mail[] = []
async send(mail: Mail) {
this.sent.push(mail)
}
/** Most recent email to `to`. */
last(to: string): Mail | undefined {
return this.sent.findLast((mail) => mail.to === to)
}
}