@unifiedcommerce/core 0.3.0 → 0.3.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.
@@ -1 +1 @@
1
- {"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../../src/auth/middleware.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAC9C,OAAO,KAAK,EAAmB,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAE1E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AA0B/C,wBAAgB,cAAc,CAC5B,IAAI,EAAE,YAAY,EAClB,MAAM,EAAE,cAAc,GACrB,iBAAiB,CA0GnB"}
1
+ {"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../../src/auth/middleware.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAC9C,OAAO,KAAK,EAAmB,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAE1E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AA0B/C,wBAAgB,cAAc,CAC5B,IAAI,EAAE,YAAY,EAClB,MAAM,EAAE,cAAc,GACrB,iBAAiB,CAwInB"}
@@ -22,10 +22,34 @@ export function authMiddleware(auth, config) {
22
22
  headers: c.req.raw.headers,
23
23
  }));
24
24
  if (session) {
25
- // Better Auth's session only stores activeOrganizationId, not the role.
26
- // Resolve role via the organization plugin's server-side API when needed.
25
+ // Better Auth's session stores activeOrganizationId, but often not the role.
26
+ // For single-store apps (org_default), users may never call set-active,
27
+ // so activeOrganizationId can be null even for valid org members.
27
28
  let role = session.session.activeOrganizationRole;
28
- if (!role && session.session.activeOrganizationId && auth.api.getActiveMemberRole) {
29
+ let orgId = session.session.activeOrganizationId;
30
+ // If no active org, try to resolve the user's membership in org_default.
31
+ // This handles the common case where the user is a member but hasn't
32
+ // called organization/set-active (single-store apps, seed scripts, tests).
33
+ const getFullOrg = auth.api.getFullOrganization;
34
+ if (!role && getFullOrg) {
35
+ try {
36
+ const org = await getFullOrg({
37
+ query: { organizationId: orgId ?? DEFAULT_ORG_ID },
38
+ });
39
+ if (org?.members) {
40
+ const membership = org.members.find((m) => m.userId === session.user.id);
41
+ if (membership) {
42
+ role = membership.role;
43
+ orgId = orgId ?? DEFAULT_ORG_ID;
44
+ }
45
+ }
46
+ }
47
+ catch {
48
+ // fall through — treat as customer
49
+ }
50
+ }
51
+ // Also try getActiveMemberRole if active org is set
52
+ if (!role && orgId && auth.api.getActiveMemberRole) {
29
53
  try {
30
54
  const roleResult = await auth.api.getActiveMemberRole({
31
55
  headers: c.req.raw.headers,
@@ -46,7 +70,7 @@ export function authMiddleware(auth, config) {
46
70
  email: session.user.email ?? null,
47
71
  name: session.user.name ?? "User",
48
72
  vendorId: session.user.vendorId ?? null,
49
- organizationId: session.session.activeOrganizationId ?? null,
73
+ organizationId: orgId ?? DEFAULT_ORG_ID,
50
74
  role: role ?? "customer",
51
75
  permissions: resolvePermissions(enrichedSession, config),
52
76
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unifiedcommerce/core",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
@@ -37,10 +37,39 @@ export function authMiddleware(
37
37
  })) as AuthSessionLike | null;
38
38
 
39
39
  if (session) {
40
- // Better Auth's session only stores activeOrganizationId, not the role.
41
- // Resolve role via the organization plugin's server-side API when needed.
40
+ // Better Auth's session stores activeOrganizationId, but often not the role.
41
+ // For single-store apps (org_default), users may never call set-active,
42
+ // so activeOrganizationId can be null even for valid org members.
42
43
  let role = session.session.activeOrganizationRole as string | undefined;
43
- if (!role && session.session.activeOrganizationId && auth.api.getActiveMemberRole) {
44
+ let orgId = session.session.activeOrganizationId as string | null;
45
+
46
+ // If no active org, try to resolve the user's membership in org_default.
47
+ // This handles the common case where the user is a member but hasn't
48
+ // called organization/set-active (single-store apps, seed scripts, tests).
49
+ const getFullOrg = auth.api.getFullOrganization as
50
+ | ((input: { query: { organizationId: string } }) => Promise<unknown>)
51
+ | undefined;
52
+ if (!role && getFullOrg) {
53
+ try {
54
+ const org = await getFullOrg({
55
+ query: { organizationId: orgId ?? DEFAULT_ORG_ID },
56
+ }) as { members?: Array<{ userId: string; role: string }> } | null;
57
+ if (org?.members) {
58
+ const membership = org.members.find(
59
+ (m: { userId: string }) => m.userId === session.user.id,
60
+ );
61
+ if (membership) {
62
+ role = membership.role;
63
+ orgId = orgId ?? DEFAULT_ORG_ID;
64
+ }
65
+ }
66
+ } catch {
67
+ // fall through — treat as customer
68
+ }
69
+ }
70
+
71
+ // Also try getActiveMemberRole if active org is set
72
+ if (!role && orgId && auth.api.getActiveMemberRole) {
44
73
  try {
45
74
  const roleResult = await auth.api.getActiveMemberRole({
46
75
  headers: c.req.raw.headers,
@@ -50,6 +79,7 @@ export function authMiddleware(
50
79
  // fall through — treat as customer
51
80
  }
52
81
  }
82
+
53
83
  const enrichedSession = {
54
84
  ...session,
55
85
  session: { ...session.session, activeOrganizationRole: role ?? null },
@@ -60,7 +90,7 @@ export function authMiddleware(
60
90
  email: session.user.email ?? null,
61
91
  name: session.user.name ?? "User",
62
92
  vendorId: session.user.vendorId ?? null,
63
- organizationId: session.session.activeOrganizationId ?? null,
93
+ organizationId: orgId ?? DEFAULT_ORG_ID,
64
94
  role: role ?? "customer",
65
95
  permissions: resolvePermissions(enrichedSession, config),
66
96
  } satisfies Actor);