@meith/settings 0.29.0 → 0.29.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@meith/settings",
3
- "version": "0.29.0",
3
+ "version": "0.29.1",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -20,7 +20,7 @@
20
20
  },
21
21
  "dependencies": {
22
22
  "zod": "^4.4.3",
23
- "@meith/core": "0.29.0",
24
- "@meith/i18n": "0.29.0"
23
+ "@meith/core": "0.29.1",
24
+ "@meith/i18n": "0.29.1"
25
25
  }
26
26
  }
@@ -3,6 +3,7 @@ import { z } from 'zod'
3
3
  import { normaliseLocale, SOURCE_LOCALE } from '@meith/i18n'
4
4
 
5
5
  import { DEFAULT_PRIVACY_POLICY, DEFAULT_TERMS_OF_SERVICE } from './legal'
6
+ import { mailEndpointProblem } from './mail'
6
7
  import { isUsableFeedUrl, isUsableIssuer, isUsableOrigin } from './origin'
7
8
 
8
9
  export type SettingGroup =
@@ -417,14 +418,16 @@ export const SETTING_DEFINITIONS = [
417
418
  'Only for the provider-API transport. The board posts Resend’s exact ' +
418
419
  'field names with a Bearer token, so this works for Resend and for ' +
419
420
  'anything that copies it — and not for Postmark or Mailgun, whose SMTP ' +
420
- 'hosts are the way in.',
421
+ 'hosts are the way in. It must be an https:// address with no embedded ' +
422
+ 'credentials, and the board refuses to reach one that resolves to a ' +
423
+ 'private or internal address.',
421
424
  schema: z
422
425
  .string()
423
426
  .trim()
424
- .refine(
425
- (value) => value === '' || z.string().url().safeParse(value).success,
426
- 'That is not a URL.',
427
- ),
427
+ .superRefine((value, ctx) => {
428
+ const problem = mailEndpointProblem(value)
429
+ if (problem !== null) ctx.addIssue({ code: z.ZodIssueCode.custom, message: problem })
430
+ }),
428
431
  default: '',
429
432
  }),
430
433
  define({
package/src/index.ts CHANGED
@@ -48,6 +48,7 @@ export {
48
48
  mailConfigFromEnvironment,
49
49
  mailConfigFromSettings,
50
50
  mailConfigProblems,
51
+ mailEndpointProblem,
51
52
  NO_MAIL,
52
53
  resolveMailConfig,
53
54
  type SmtpMailConfig,
package/src/mail.ts CHANGED
@@ -175,6 +175,24 @@ function hostOf(endpoint: string): string {
175
175
  }
176
176
  }
177
177
 
178
+ export function mailEndpointProblem(value: string): string | null {
179
+ const trimmed = value.trim()
180
+ if (trimmed === '') return null
181
+
182
+ let url: URL
183
+ try {
184
+ url = new URL(trimmed)
185
+ } catch {
186
+ return 'That is not a URL.'
187
+ }
188
+
189
+ if (url.protocol !== 'https:') return 'The endpoint must be an https:// URL.'
190
+ if (url.username !== '' || url.password !== '') {
191
+ return 'The endpoint must not carry a username or password.'
192
+ }
193
+ return null
194
+ }
195
+
178
196
  export interface MailPreset {
179
197
  readonly id: string
180
198
  readonly label: string