Skip to content

Commit 8e501b9

Browse files
Copilothotlong
andcommitted
Fix storage-agnostic adapter and RBAC integration issues
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
1 parent e8c33b5 commit 8e501b9

2 files changed

Lines changed: 56 additions & 27 deletions

File tree

src/adapter/index.ts

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -143,13 +143,21 @@ export function createObjectQLAdapter(config: ObjectQLAdapterConfig): Adapter {
143143
accountId: string,
144144
data: Partial<AdapterAccount>
145145
): Promise<AdapterAccount> {
146-
const account = await ql.entity('Account').update({
146+
// Storage-agnostic approach: Find by composite fields, then update by ID
147+
// This avoids Prisma-specific compound key syntax that may not work with all ObjectQL drivers
148+
const existingAccount = await ql.entity('Account').findFirst({
147149
where: {
148-
providerId_accountId: {
149-
providerId,
150-
accountId,
151-
},
150+
providerId,
151+
accountId,
152152
},
153+
});
154+
155+
if (!existingAccount) {
156+
throw new Error(`Account not found: ${providerId}/${accountId}`);
157+
}
158+
159+
const account = await ql.entity('Account').update({
160+
where: { id: existingAccount.id },
153161
data: {
154162
...data,
155163
updatedAt: new Date(),
@@ -159,12 +167,11 @@ export function createObjectQLAdapter(config: ObjectQLAdapterConfig): Adapter {
159167
},
160168

161169
async deleteAccount(providerId: string, accountId: string): Promise<void> {
162-
await ql.entity('Account').delete({
170+
// Use deleteMany with where clause for storage-agnostic deletion
171+
await ql.entity('Account').deleteMany({
163172
where: {
164-
providerId_accountId: {
165-
providerId,
166-
accountId,
167-
},
173+
providerId,
174+
accountId,
168175
},
169176
});
170177
},

src/server/index.ts

Lines changed: 39 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -86,32 +86,45 @@ export function createAuthServer(config: ObjectStackAuthServerConfig) {
8686
// Create Better-Auth instance
8787
const auth = betterAuth(authOptions);
8888

89-
// RBAC Integration: Inject permissions into session
90-
// This is a custom plugin hook that runs after session retrieval
91-
if (onGetPermissions) {
92-
const originalGetSession = auth.api.getSession.bind(auth.api);
93-
auth.api.getSession = async (request: any) => {
94-
const session = await originalGetSession(request);
89+
// RBAC Integration: Enhanced session retrieval with permissions
90+
// Note: This wraps the session retrieval to inject permissions
91+
// If Better-Auth provides official plugin hooks in the future, migrate to those
92+
return {
93+
...auth,
94+
95+
// Enhanced getSession that includes permissions
96+
getSessionWithPermissions: async (request: Request) => {
97+
const session = await auth.api.getSession({ request });
9598

96-
if (session?.user?.id) {
99+
if (session?.user?.id && onGetPermissions) {
97100
try {
98101
// Query ObjectOS for user permissions
99102
const permissions = await onGetPermissions(session.user.id);
100103

101-
// Inject permissions into session object
102-
session.user.permissions = permissions;
104+
// Return enhanced session with permissions
105+
return {
106+
...session,
107+
user: {
108+
...session.user,
109+
permissions,
110+
},
111+
};
103112
} catch (error) {
104113
console.error('Failed to load user permissions:', error);
105-
// Don't fail the session if permissions fail to load
106-
session.user.permissions = null;
114+
// Return session without permissions on error
115+
return {
116+
...session,
117+
user: {
118+
...session.user,
119+
permissions: null,
120+
},
121+
};
107122
}
108123
}
109124

110125
return session;
111-
};
112-
}
113-
114-
return auth;
126+
},
127+
};
115128
}
116129

117130
/**
@@ -136,8 +149,17 @@ export interface ObjectStackSession {
136149
}
137150

138151
/**
139-
* Utility to extract session from request
152+
* Utility to extract session with permissions from request
140153
*/
141-
export async function getSession(auth: ReturnType<typeof createAuthServer>, request: Request): Promise<ObjectStackSession | null> {
154+
export async function getSession(
155+
auth: ReturnType<typeof createAuthServer>,
156+
request: Request
157+
): Promise<ObjectStackSession | null> {
158+
// Use the enhanced getSessionWithPermissions if available
159+
if ('getSessionWithPermissions' in auth && typeof auth.getSessionWithPermissions === 'function') {
160+
return await auth.getSessionWithPermissions(request) as ObjectStackSession | null;
161+
}
162+
163+
// Fallback to standard getSession
142164
return await auth.api.getSession({ request }) as ObjectStackSession | null;
143165
}

0 commit comments

Comments
 (0)