@jskit-ai/auth-provider-supabase-core 0.1.96 → 0.1.98

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.
@@ -1,7 +1,7 @@
1
1
  export default Object.freeze({
2
2
  "packageVersion": 1,
3
3
  "packageId": "@jskit-ai/auth-provider-supabase-core",
4
- "version": "0.1.96",
4
+ "version": "0.1.98",
5
5
  "kind": "runtime",
6
6
  "options": {
7
7
  "auth-supabase-url": {
@@ -83,8 +83,8 @@ export default Object.freeze({
83
83
  "mutations": {
84
84
  "dependencies": {
85
85
  "runtime": {
86
- "@jskit-ai/auth-core": "0.1.96",
87
- "@jskit-ai/kernel": "0.1.98",
86
+ "@jskit-ai/auth-core": "0.1.97",
87
+ "@jskit-ai/kernel": "0.1.99",
88
88
  "dotenv": "^16.4.5",
89
89
  "@supabase/supabase-js": "^2.57.4",
90
90
  "jose": "^6.1.0"
@@ -137,8 +137,21 @@ export default Object.freeze({
137
137
  "op": "append-text",
138
138
  "file": "config/server.js",
139
139
  "position": "bottom",
140
- "skipIfContains": "config.auth = {",
141
- "value": "\nconfig.auth = {\n oauth: {\n providers: [],\n defaultProvider: \"\"\n }\n};\n",
140
+ "skipIfContains": "config.auth.profileMode =",
141
+ "value": "\nconfig.auth ||= {};\nconfig.auth.profileMode = \"standalone\";\n",
142
+ "reason": "Use standalone auth profile sync until a users package enables users-backed sync.",
143
+ "category": "runtime-config",
144
+ "id": "auth-profile-mode-standalone"
145
+ },
146
+ {
147
+ "op": "append-text",
148
+ "file": "config/server.js",
149
+ "position": "bottom",
150
+ "skipIfContains": [
151
+ "config.auth.oauth = {",
152
+ "config.auth = {\n oauth: {"
153
+ ],
154
+ "value": "\nconfig.auth ||= {};\nconfig.auth.oauth = {\n providers: [],\n defaultProvider: \"\"\n};\n",
142
155
  "reason": "Append app-owned OAuth provider visibility config for stock auth screens.",
143
156
  "category": "runtime-config",
144
157
  "id": "auth-oauth-app-config"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jskit-ai/auth-provider-supabase-core",
3
- "version": "0.1.96",
3
+ "version": "0.1.98",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "test": "node --test"
@@ -12,8 +12,8 @@
12
12
  "./client": "./src/client/index.js"
13
13
  },
14
14
  "dependencies": {
15
- "@jskit-ai/auth-core": "0.1.96",
16
- "@jskit-ai/kernel": "0.1.98",
15
+ "@jskit-ai/auth-core": "0.1.97",
16
+ "@jskit-ai/kernel": "0.1.99",
17
17
  "json-rest-schema": "1.x.x",
18
18
  "jose": "^6.1.0",
19
19
  "@supabase/supabase-js": "^2.57.4",
@@ -6,9 +6,9 @@ import { createService } from "../lib/service.js";
6
6
  import { createStandaloneProfileSyncService } from "../lib/standaloneProfileSyncService.js";
7
7
  import { createAuthSessionEventsService } from "../lib/authSessionEventsService.js";
8
8
  import { buildAuthActions } from "../lib/actions/auth.contributor.js";
9
- const AUTH_PROFILE_MODE_STANDALONE = "standalone";
10
- const AUTH_PROFILE_MODE_USERS = "users";
11
- const SUPPORTED_AUTH_PROFILE_MODES = Object.freeze([AUTH_PROFILE_MODE_STANDALONE, AUTH_PROFILE_MODE_USERS]);
9
+ const PROFILE_MODE_STANDALONE = "standalone";
10
+ const PROFILE_MODE_USERS = "users";
11
+ const SUPPORTED_PROFILE_MODES = Object.freeze([PROFILE_MODE_STANDALONE, PROFILE_MODE_USERS]);
12
12
  const INTERNAL_JSON_REST_API = "internal.json-rest-api";
13
13
 
14
14
  function splitCsv(value) {
@@ -91,16 +91,16 @@ function resolveAuthProviderConfig(env, appConfig = {}) {
91
91
  };
92
92
  }
93
93
 
94
- function resolveAuthProfileMode(env) {
95
- const source = env && typeof env === "object" ? env : {};
96
- const mode = String(source.AUTH_PROFILE_MODE || AUTH_PROFILE_MODE_STANDALONE)
94
+ function resolveAuthProfileMode(appConfig = {}) {
95
+ const auth = normalizeRecord(normalizeRecord(appConfig).auth);
96
+ const mode = String(auth.profileMode || PROFILE_MODE_USERS)
97
97
  .trim()
98
98
  .toLowerCase();
99
- if (SUPPORTED_AUTH_PROFILE_MODES.includes(mode)) {
99
+ if (SUPPORTED_PROFILE_MODES.includes(mode)) {
100
100
  return mode;
101
101
  }
102
102
  throw new Error(
103
- `Unsupported AUTH_PROFILE_MODE "${mode}". Supported values: ${SUPPORTED_AUTH_PROFILE_MODES.join(", ")}.`
103
+ `Unsupported config.auth.profileMode "${mode}". Supported values: ${SUPPORTED_PROFILE_MODES.join(", ")}.`
104
104
  );
105
105
  }
106
106
 
@@ -244,12 +244,12 @@ class AuthSupabaseServiceProvider {
244
244
  return null;
245
245
  }
246
246
  }
247
- const authProfileMode = resolveAuthProfileMode(env);
247
+ const authProfileMode = resolveAuthProfileMode(appConfig);
248
248
  let userProfileSyncService = fallbackStandaloneProfileSyncService;
249
- if (authProfileMode === AUTH_PROFILE_MODE_USERS) {
249
+ if (authProfileMode === PROFILE_MODE_USERS) {
250
250
  if (!scope.has("users.profile.sync.service")) {
251
251
  throw new Error(
252
- "AuthSupabaseServiceProvider requires users.profile.sync.service when AUTH_PROFILE_MODE=users."
252
+ "AuthSupabaseServiceProvider requires users.profile.sync.service when config.auth.profileMode is \"users\"."
253
253
  );
254
254
  }
255
255
  userProfileSyncService = scope.make("users.profile.sync.service");
@@ -6,8 +6,8 @@ import { ActionRuntimeServiceProvider } from "@jskit-ai/kernel/server/actions";
6
6
  import { createProviderClass } from "../../kernel/shared/runtime/application.js";
7
7
  import { AuthSupabaseServiceProvider } from "../src/server/providers/AuthSupabaseServiceProvider.js";
8
8
 
9
- function createAppConfigFixture() {
10
- return {
9
+ function createAppConfigFixture({ auth = null } = {}) {
10
+ const config = {
11
11
  surfaceModeAll: "all",
12
12
  surfaceDefaultId: "home",
13
13
  surfaceDefinitions: {
@@ -21,6 +21,10 @@ function createAppConfigFixture() {
21
21
  }
22
22
  }
23
23
  };
24
+ if (auth && typeof auth === "object") {
25
+ config.auth = auth;
26
+ }
27
+ return config;
24
28
  }
25
29
 
26
30
  function isBootFailureWithCause(error, pattern) {
@@ -31,13 +35,12 @@ function isBootFailureWithCause(error, pattern) {
31
35
  );
32
36
  }
33
37
 
34
- test("auth supabase provider registers authService and contributes auth actions in users mode", async () => {
38
+ test("auth supabase provider defaults to users mode and contributes auth actions", async () => {
35
39
  const app = createApplication();
36
40
  app.instance("appConfig", createAppConfigFixture());
37
41
  app.instance("jskit.env", {
38
42
  AUTH_SUPABASE_URL: "https://example.supabase.co",
39
43
  AUTH_SUPABASE_PUBLISHABLE_KEY: "sb_publishable_test_key",
40
- AUTH_PROFILE_MODE: "users",
41
44
  APP_PUBLIC_URL: "http://localhost:5173",
42
45
  NODE_ENV: "test"
43
46
  });
@@ -86,11 +89,14 @@ test("auth supabase provider registers authService and contributes auth actions
86
89
 
87
90
  test("auth supabase provider registers authService in standalone mode without users.profile.sync.service", async () => {
88
91
  const app = createApplication();
89
- app.instance("appConfig", createAppConfigFixture());
92
+ app.instance("appConfig", createAppConfigFixture({
93
+ auth: {
94
+ profileMode: "standalone"
95
+ }
96
+ }));
90
97
  app.instance("jskit.env", {
91
98
  AUTH_SUPABASE_URL: "https://example.supabase.co",
92
99
  AUTH_SUPABASE_PUBLISHABLE_KEY: "sb_publishable_test_key",
93
- AUTH_PROFILE_MODE: "standalone",
94
100
  APP_PUBLIC_URL: "http://localhost:5173",
95
101
  NODE_ENV: "test"
96
102
  });
@@ -112,13 +118,12 @@ test("auth supabase provider registers authService in standalone mode without us
112
118
  assert.equal(typeof authService?.login, "function");
113
119
  });
114
120
 
115
- test("auth supabase provider requires users.profile.sync.service when AUTH_PROFILE_MODE=users", async () => {
121
+ test("auth supabase provider requires users.profile.sync.service in default users mode", async () => {
116
122
  const app = createApplication();
117
123
  app.instance("appConfig", createAppConfigFixture());
118
124
  app.instance("jskit.env", {
119
125
  AUTH_SUPABASE_URL: "https://example.supabase.co",
120
126
  AUTH_SUPABASE_PUBLISHABLE_KEY: "sb_publishable_test_key",
121
- AUTH_PROFILE_MODE: "users",
122
127
  APP_PUBLIC_URL: "http://localhost:5173",
123
128
  NODE_ENV: "test"
124
129
  });
@@ -136,16 +141,19 @@ test("auth supabase provider requires users.profile.sync.service when AUTH_PROFI
136
141
  providers: [ActionRuntimeServiceProvider, AuthSupabaseServiceProvider]
137
142
  });
138
143
 
139
- assert.throws(() => app.make("authService"), /AUTH_PROFILE_MODE=users/);
144
+ assert.throws(() => app.make("authService"), /config\.auth\.profileMode is "users"/);
140
145
  });
141
146
 
142
- test("auth supabase provider rejects unsupported AUTH_PROFILE_MODE values", async () => {
147
+ test("auth supabase provider rejects unsupported config.auth.profileMode values", async () => {
143
148
  const app = createApplication();
144
- app.instance("appConfig", createAppConfigFixture());
149
+ app.instance("appConfig", createAppConfigFixture({
150
+ auth: {
151
+ profileMode: "invalid"
152
+ }
153
+ }));
145
154
  app.instance("jskit.env", {
146
155
  AUTH_SUPABASE_URL: "https://example.supabase.co",
147
156
  AUTH_SUPABASE_PUBLISHABLE_KEY: "sb_publishable_test_key",
148
- AUTH_PROFILE_MODE: "invalid",
149
157
  APP_PUBLIC_URL: "http://localhost:5173",
150
158
  NODE_ENV: "test"
151
159
  });
@@ -163,7 +171,7 @@ test("auth supabase provider rejects unsupported AUTH_PROFILE_MODE values", asyn
163
171
  providers: [ActionRuntimeServiceProvider, AuthSupabaseServiceProvider]
164
172
  });
165
173
 
166
- assert.throws(() => app.make("authService"), /Unsupported AUTH_PROFILE_MODE/);
174
+ assert.throws(() => app.make("authService"), /Unsupported config\.auth\.profileMode/);
167
175
  });
168
176
 
169
177
  test("auth supabase provider can boot dev auth without Supabase credentials", async () => {
@@ -172,7 +180,6 @@ test("auth supabase provider can boot dev auth without Supabase credentials", as
172
180
  app.instance("jskit.env", {
173
181
  AUTH_DEV_BYPASS_ENABLED: "true",
174
182
  AUTH_DEV_BYPASS_SECRET: "dev-bootstrap-secret",
175
- AUTH_PROFILE_MODE: "users",
176
183
  APP_PUBLIC_URL: "http://localhost:5173",
177
184
  NODE_ENV: "development"
178
185
  });
@@ -224,11 +231,14 @@ test("auth supabase provider can boot dev auth without Supabase credentials", as
224
231
 
225
232
  test("auth supabase provider applies registered auth service decorators", async () => {
226
233
  const app = createApplication();
227
- app.instance("appConfig", createAppConfigFixture());
234
+ app.instance("appConfig", createAppConfigFixture({
235
+ auth: {
236
+ profileMode: "standalone"
237
+ }
238
+ }));
228
239
  app.instance("jskit.env", {
229
240
  AUTH_SUPABASE_URL: "https://example.supabase.co",
230
241
  AUTH_SUPABASE_PUBLISHABLE_KEY: "sb_publishable_test_key",
231
- AUTH_PROFILE_MODE: "standalone",
232
242
  APP_PUBLIC_URL: "http://localhost:5173",
233
243
  NODE_ENV: "test"
234
244
  });
@@ -268,7 +278,6 @@ test("auth supabase provider rejects dev auth bypass in production", async () =>
268
278
  app.instance("jskit.env", {
269
279
  AUTH_DEV_BYPASS_ENABLED: "true",
270
280
  AUTH_DEV_BYPASS_SECRET: "dev-bootstrap-secret",
271
- AUTH_PROFILE_MODE: "users",
272
281
  APP_PUBLIC_URL: "https://example.com",
273
282
  NODE_ENV: "production"
274
283
  });
@@ -318,7 +327,6 @@ test("auth supabase provider rejects dev auth bypass without a secret during boo
318
327
  app.instance("appConfig", createAppConfigFixture());
319
328
  app.instance("jskit.env", {
320
329
  AUTH_DEV_BYPASS_ENABLED: "true",
321
- AUTH_PROFILE_MODE: "users",
322
330
  APP_PUBLIC_URL: "http://localhost:5173",
323
331
  NODE_ENV: "development"
324
332
  });
@@ -369,7 +377,6 @@ test("auth supabase provider rejects dev auth bypass without internal.repository
369
377
  app.instance("jskit.env", {
370
378
  AUTH_DEV_BYPASS_ENABLED: "true",
371
379
  AUTH_DEV_BYPASS_SECRET: "dev-bootstrap-secret",
372
- AUTH_PROFILE_MODE: "users",
373
380
  APP_PUBLIC_URL: "http://localhost:5173",
374
381
  NODE_ENV: "development"
375
382
  });
@@ -440,7 +447,6 @@ test("auth supabase provider defers eager dev auth materialization until json-re
440
447
  app.instance("jskit.env", {
441
448
  AUTH_DEV_BYPASS_ENABLED: "true",
442
449
  AUTH_DEV_BYPASS_SECRET: "dev-bootstrap-secret",
443
- AUTH_PROFILE_MODE: "users",
444
450
  APP_PUBLIC_URL: "http://localhost:5173",
445
451
  NODE_ENV: "development"
446
452
  });
@@ -486,6 +492,7 @@ test("auth supabase provider reads oauth providers from appConfig.auth.oauth", a
486
492
  app.instance("appConfig", {
487
493
  ...createAppConfigFixture(),
488
494
  auth: {
495
+ profileMode: "standalone",
489
496
  oauth: {
490
497
  providers: ["github"],
491
498
  defaultProvider: "github"
@@ -495,7 +502,6 @@ test("auth supabase provider reads oauth providers from appConfig.auth.oauth", a
495
502
  app.instance("jskit.env", {
496
503
  AUTH_SUPABASE_URL: "https://example.supabase.co",
497
504
  AUTH_SUPABASE_PUBLISHABLE_KEY: "sb_publishable_test_key",
498
- AUTH_PROFILE_MODE: "standalone",
499
505
  APP_PUBLIC_URL: "http://localhost:5173",
500
506
  NODE_ENV: "test"
501
507
  });
@@ -524,6 +530,7 @@ test("auth supabase provider lets env oauth settings override appConfig.auth.oau
524
530
  app.instance("appConfig", {
525
531
  ...createAppConfigFixture(),
526
532
  auth: {
533
+ profileMode: "standalone",
527
534
  oauth: {
528
535
  providers: ["github"],
529
536
  defaultProvider: "github"
@@ -535,7 +542,6 @@ test("auth supabase provider lets env oauth settings override appConfig.auth.oau
535
542
  AUTH_SUPABASE_PUBLISHABLE_KEY: "sb_publishable_test_key",
536
543
  AUTH_OAUTH_PROVIDERS: "google",
537
544
  AUTH_OAUTH_DEFAULT_PROVIDER: "google",
538
- AUTH_PROFILE_MODE: "standalone",
539
545
  APP_PUBLIC_URL: "http://localhost:5173",
540
546
  NODE_ENV: "test"
541
547
  });