@karmaniverous/jeeves-server-core 0.1.5 → 0.1.6

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.
@@ -5,5 +5,5 @@
5
5
  */
6
6
  export { computeDeepShareKey, computeInsiderKey, computeOutsiderKeyWithExpiry, computePathKey, type DeepShareParams, timingSafeEqual, } from './crypto.js';
7
7
  export { type EndpointEntry, serverEndpoints } from './endpoints.js';
8
- export { type AuthMode, authModeSchema, authSchema, DEPRECATED_CONFIG_PROPS, eventConfigSchema, googleAuthSchema, insiderEntrySchema, isScopeName, type JeevesConfig, jeevesConfigSchema, keyEntrySchema, type LoggingConfig, loggingConfigSchema, oauthProviderSchema, oauthSchema, scopesObjectSchema, scopesSchema, } from './schema.js';
8
+ export { type AuthMode, authModeSchema, authSchema, type Branding, brandingSchema, DEFAULT_BRANDING, DEPRECATED_CONFIG_PROPS, emailAuthSchema, eventConfigSchema, googleAuthSchema, insiderEntrySchema, isScopeName, type JeevesConfig, jeevesConfigSchema, keyEntrySchema, type LoggingConfig, loggingConfigSchema, oauthProviderSchema, oauthSchema, scopesObjectSchema, scopesSchema, themeOverridesSchema, } from './schema.js';
9
9
  export type { AuthStatusResponse, DriveEntry, ExportCacheClearResponse, ExportLink, FileMutationAction, LinkInfoResponse, OAuthStartRequest, OAuthStartResponse, RotateKeyResponse, ShareForRequest, ShareForResponse, ShareRequest, ShareResponse, } from './types.js';
package/dist/src/index.js CHANGED
@@ -1,3 +1,3 @@
1
1
  export { computeDeepShareKey, computeInsiderKey, computeOutsiderKeyWithExpiry, computePathKey, timingSafeEqual } from './crypto.js';
2
2
  export { serverEndpoints } from './endpoints.js';
3
- export { DEPRECATED_CONFIG_PROPS, authModeSchema, authSchema, eventConfigSchema, googleAuthSchema, insiderEntrySchema, isScopeName, jeevesConfigSchema, keyEntrySchema, loggingConfigSchema, oauthProviderSchema, oauthSchema, scopesObjectSchema, scopesSchema } from './schema.js';
3
+ export { DEFAULT_BRANDING, DEPRECATED_CONFIG_PROPS, authModeSchema, authSchema, brandingSchema, emailAuthSchema, eventConfigSchema, googleAuthSchema, insiderEntrySchema, isScopeName, jeevesConfigSchema, keyEntrySchema, loggingConfigSchema, oauthProviderSchema, oauthSchema, scopesObjectSchema, scopesSchema, themeOverridesSchema } from './schema.js';
@@ -5,23 +5,34 @@ export declare const DEPRECATED_CONFIG_PROPS: readonly ["host", "runnerUrl", "wa
5
5
  export declare const authModeSchema: z.ZodEnum<{
6
6
  keys: "keys";
7
7
  google: "google";
8
+ email: "email";
8
9
  }>;
9
10
  /** Google OAuth configuration */
10
11
  export declare const googleAuthSchema: z.ZodObject<{
11
12
  clientId: z.ZodString;
12
13
  clientSecret: z.ZodString;
13
14
  }, z.core.$strip>;
15
+ /** Email (magic link) authentication configuration */
16
+ export declare const emailAuthSchema: z.ZodObject<{
17
+ smtpUrl: z.ZodString;
18
+ fromAddress: z.ZodEmail;
19
+ }, z.core.$strip>;
14
20
  /** Auth configuration */
15
21
  export declare const authSchema: z.ZodObject<{
16
22
  modes: z.ZodArray<z.ZodEnum<{
17
23
  keys: "keys";
18
24
  google: "google";
25
+ email: "email";
19
26
  }>>;
20
27
  google: z.ZodOptional<z.ZodObject<{
21
28
  clientId: z.ZodString;
22
29
  clientSecret: z.ZodString;
23
30
  }, z.core.$strip>>;
24
31
  sessionSecret: z.ZodOptional<z.ZodString>;
32
+ email: z.ZodOptional<z.ZodObject<{
33
+ smtpUrl: z.ZodString;
34
+ fromAddress: z.ZodEmail;
35
+ }, z.core.$strip>>;
25
36
  }, z.core.$strip>;
26
37
  /** Event webhook configuration */
27
38
  export declare const eventConfigSchema: z.ZodObject<{
@@ -99,6 +110,18 @@ export declare const oauthSchema: z.ZodObject<{
99
110
  defaultScopes: z.ZodDefault<z.ZodArray<z.ZodString>>;
100
111
  }, z.core.$strip>>>;
101
112
  }, z.core.$strip>;
113
+ /** Theme overrides for light and dark modes */
114
+ export declare const themeOverridesSchema: z.ZodRecord<z.ZodString, z.ZodString>;
115
+ /** Instance branding configuration */
116
+ export declare const brandingSchema: z.ZodObject<{
117
+ name: z.ZodDefault<z.ZodString>;
118
+ emoji: z.ZodDefault<z.ZodString>;
119
+ theme: z.ZodOptional<z.ZodObject<{
120
+ light: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
121
+ dark: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
122
+ }, z.core.$strip>>;
123
+ emailTemplate: z.ZodOptional<z.ZodString>;
124
+ }, z.core.$strip>;
102
125
  /** Top-level Jeeves Server configuration */
103
126
  export declare const jeevesConfigSchema: z.ZodObject<{
104
127
  port: z.ZodDefault<z.ZodNumber>;
@@ -107,12 +130,17 @@ export declare const jeevesConfigSchema: z.ZodObject<{
107
130
  modes: z.ZodArray<z.ZodEnum<{
108
131
  keys: "keys";
109
132
  google: "google";
133
+ email: "email";
110
134
  }>>;
111
135
  google: z.ZodOptional<z.ZodObject<{
112
136
  clientId: z.ZodString;
113
137
  clientSecret: z.ZodString;
114
138
  }, z.core.$strip>>;
115
139
  sessionSecret: z.ZodOptional<z.ZodString>;
140
+ email: z.ZodOptional<z.ZodObject<{
141
+ smtpUrl: z.ZodString;
142
+ fromAddress: z.ZodEmail;
143
+ }, z.core.$strip>>;
116
144
  }, z.core.$strip>;
117
145
  scopes: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
118
146
  allow: z.ZodOptional<z.ZodArray<z.ZodString>>;
@@ -172,8 +200,24 @@ export declare const jeevesConfigSchema: z.ZodObject<{
172
200
  }, z.core.$strip>>>;
173
201
  }, z.core.$strip>>;
174
202
  go: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodString>>;
203
+ branding: z.ZodOptional<z.ZodObject<{
204
+ name: z.ZodDefault<z.ZodString>;
205
+ emoji: z.ZodDefault<z.ZodString>;
206
+ theme: z.ZodOptional<z.ZodObject<{
207
+ light: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
208
+ dark: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
209
+ }, z.core.$strip>>;
210
+ emailTemplate: z.ZodOptional<z.ZodString>;
211
+ }, z.core.$strip>>;
175
212
  }, z.core.$strip>;
176
213
  /** Inferred config type */
177
214
  export type JeevesConfig = z.infer<typeof jeevesConfigSchema>;
178
215
  /** Auth mode type */
179
216
  export type AuthMode = z.infer<typeof authModeSchema>;
217
+ /** Inferred branding type */
218
+ export type Branding = z.infer<typeof brandingSchema>;
219
+ /** Default branding values. Single source of truth for all fallbacks. */
220
+ export declare const DEFAULT_BRANDING: {
221
+ readonly name: "Jeeves Server";
222
+ readonly emoji: "🎩";
223
+ };
@@ -9,12 +9,19 @@ const DEPRECATED_CONFIG_PROPS = [
9
9
  'metaUrl',
10
10
  ];
11
11
  /** Supported authentication methods */
12
- const authModeSchema = z.enum(['google', 'keys']);
12
+ const authModeSchema = z.enum(['google', 'keys', 'email']);
13
13
  /** Google OAuth configuration */
14
14
  const googleAuthSchema = z.object({
15
15
  clientId: z.string().min(1),
16
16
  clientSecret: z.string().min(1),
17
17
  });
18
+ /** Email (magic link) authentication configuration */
19
+ const emailAuthSchema = z.object({
20
+ /** SMTP connection string (e.g. smtps://user:pass@smtp.example.com:465) */
21
+ smtpUrl: z.string().min(1),
22
+ /** Sender email address for magic link emails */
23
+ fromAddress: z.email(),
24
+ });
18
25
  /** Auth configuration */
19
26
  const authSchema = z.object({
20
27
  /** Active authentication methods. Order determines priority. */
@@ -25,6 +32,8 @@ const authSchema = z.object({
25
32
  google: googleAuthSchema.optional(),
26
33
  /** Session cookie signing secret. Required if modes includes "google". */
27
34
  sessionSecret: z.string().min(1).optional(),
35
+ /** Email (magic link) auth config. Required if modes includes "email". */
36
+ email: emailAuthSchema.optional(),
28
37
  });
29
38
  /** Event webhook configuration */
30
39
  const eventConfigSchema = z.object({
@@ -126,6 +135,24 @@ const oauthSchema = z.object({
126
135
  credentialDir: z.string(),
127
136
  providers: z.record(z.string(), oauthProviderSchema).default({}),
128
137
  });
138
+ /** Theme overrides for light and dark modes */
139
+ const themeOverridesSchema = z.record(z.string(), z.string());
140
+ /** Instance branding configuration */
141
+ const brandingSchema = z.object({
142
+ /** Instance display name (used in page title, navbar, emails) */
143
+ name: z.string().default('Jeeves Server'),
144
+ /** Instance emoji (used as home icon in navbar) */
145
+ emoji: z.string().default('🎩'),
146
+ /** CSS variable overrides grouped by theme mode */
147
+ theme: z
148
+ .object({
149
+ light: themeOverridesSchema.optional(),
150
+ dark: themeOverridesSchema.optional(),
151
+ })
152
+ .optional(),
153
+ /** Handlebars template for magic link emails. Supports {{magicLink}}, {{branding.name}}, {{branding.emoji}} */
154
+ emailTemplate: z.string().optional(),
155
+ });
129
156
  /** Top-level Jeeves Server configuration */
130
157
  const jeevesConfigSchema = z
131
158
  .object({
@@ -198,6 +225,8 @@ const jeevesConfigSchema = z
198
225
  message: 'Target must be a relative path starting with / or an absolute URL',
199
226
  }))
200
227
  .default({}),
228
+ /** Instance branding (name, emoji, theme overrides, email template) */
229
+ branding: brandingSchema.optional(),
201
230
  })
202
231
  .superRefine((config, ctx) => {
203
232
  // Google auth mode requires google config + sessionSecret
@@ -217,6 +246,23 @@ const jeevesConfigSchema = z
217
246
  });
218
247
  }
219
248
  }
249
+ // Email auth mode requires email config
250
+ if (config.auth.modes.includes('email')) {
251
+ if (!config.auth.email) {
252
+ ctx.addIssue({
253
+ code: 'custom',
254
+ message: 'auth.email is required when auth.modes includes "email"',
255
+ path: ['auth', 'email'],
256
+ });
257
+ }
258
+ if (!config.auth.sessionSecret) {
259
+ ctx.addIssue({
260
+ code: 'custom',
261
+ message: 'auth.sessionSecret is required when auth.modes includes "email"',
262
+ path: ['auth', 'sessionSecret'],
263
+ });
264
+ }
265
+ }
220
266
  // Keys auth mode requires at least one key
221
267
  if (config.auth.modes.includes('keys') &&
222
268
  Object.keys(config.keys).length === 0) {
@@ -266,5 +312,10 @@ const jeevesConfigSchema = z
266
312
  if (outsiderRefs.length > 0)
267
313
  validateRefs(outsiderRefs, ['outsiderPolicy']);
268
314
  });
315
+ /** Default branding values. Single source of truth for all fallbacks. */
316
+ const DEFAULT_BRANDING = {
317
+ name: 'Jeeves Server',
318
+ emoji: '🎩',
319
+ };
269
320
 
270
- export { DEPRECATED_CONFIG_PROPS, authModeSchema, authSchema, eventConfigSchema, googleAuthSchema, insiderEntrySchema, isScopeName, jeevesConfigSchema, keyEntrySchema, loggingConfigSchema, oauthProviderSchema, oauthSchema, scopesObjectSchema, scopesSchema };
321
+ export { DEFAULT_BRANDING, DEPRECATED_CONFIG_PROPS, authModeSchema, authSchema, brandingSchema, emailAuthSchema, eventConfigSchema, googleAuthSchema, insiderEntrySchema, isScopeName, jeevesConfigSchema, keyEntrySchema, loggingConfigSchema, oauthProviderSchema, oauthSchema, scopesObjectSchema, scopesSchema, themeOverridesSchema };
package/package.json CHANGED
@@ -86,5 +86,5 @@
86
86
  },
87
87
  "type": "module",
88
88
  "types": "dist/src/index.d.ts",
89
- "version": "0.1.5"
89
+ "version": "0.1.6"
90
90
  }