Skip to content

Commit dda159f

Browse files
committed
✨ feat: add sso fetcher in services
1 parent 89a60e3 commit dda159f

File tree

6 files changed

+47
-1
lines changed

6 files changed

+47
-1
lines changed

src/database/server/models/user.ts

+28-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { TRPCError } from '@trpc/server';
22
import dayjs from 'dayjs';
33
import { eq } from 'drizzle-orm/expressions';
4+
import type { AdapterAccount } from 'next-auth/adapters';
45
import { DeepPartial } from 'utility-types';
56

67
import { LobeChatDatabase } from '@/database/type';
@@ -9,7 +10,14 @@ import { UserKeyVaults, UserSettings } from '@/types/user/settings';
910
import { merge } from '@/utils/merge';
1011
import { today } from '@/utils/time';
1112

12-
import { NewUser, UserItem, UserSettingsItem, userSettings, users } from '../../schemas';
13+
import {
14+
NewUser,
15+
UserItem,
16+
UserSettingsItem,
17+
nextauthAccounts,
18+
userSettings,
19+
users,
20+
} from '../../schemas';
1321
import { SessionModel } from './session';
1422

1523
type DecryptUserKeyVaults = (
@@ -97,6 +105,25 @@ export class UserModel {
97105
};
98106
};
99107

108+
getUserSSOProviders = async () => {
109+
return this.db.query.nextauthAccounts
110+
.findMany({
111+
where: eq(nextauthAccounts.userId, this.userId),
112+
})
113+
.then((accounts) =>
114+
accounts.map((account) => {
115+
// Pick necessary fields, don't expose the sensitive information
116+
return {
117+
expires_at: account?.expires_at,
118+
provider: account?.provider,
119+
providerAccountId: account?.providerAccountId,
120+
scope: account?.scope,
121+
type: account?.type,
122+
} as unknown as AdapterAccount;
123+
}),
124+
) as Promise<AdapterAccount[]>;
125+
};
126+
100127
getUserSettings = async () => {
101128
return this.db.query.userSettings.findFirst({ where: eq(userSettings.id, this.userId) });
102129
};

src/server/routers/lambda/user.ts

+4
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ export const userRouter = router({
2424
return ctx.userModel.getUserRegistrationDuration();
2525
}),
2626

27+
getUserSSOProviders: userProcedure.query(async ({ ctx }) => {
28+
return ctx.userModel.getUserSSOProviders();
29+
}),
30+
2731
getUserState: userProcedure.query(async ({ ctx }): Promise<UserInitializationState> => {
2832
let state: Awaited<ReturnType<UserModel['getUserState']>> | undefined;
2933

src/services/user/_deprecated.ts

+4
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ export class ClientService implements IUserService {
3737
};
3838
}
3939

40+
getUserSSOProviders = async () => {
41+
return [];
42+
};
43+
4044
// eslint-disable-next-line @typescript-eslint/no-unused-vars
4145
updateUserSettings = async (patch: DeepPartial<UserSettings>, _?: any) => {
4246
return UserModel.updateSettings(patch);

src/services/user/client.ts

+5
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,11 @@ export class ClientService extends BaseClientService implements IUserService {
5454
};
5555
};
5656

57+
getUserSSOProviders: IUserService['getUserSSOProviders'] = async () => {
58+
// Account not exist on next-auth in client mode
59+
return [];
60+
};
61+
5762
updateUserSettings: IUserService['updateUserSettings'] = async (value) => {
5863
const { keyVaults, ...res } = value;
5964

src/services/user/server.ts

+4
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ export class ServerService implements IUserService {
1010
return lambdaClient.user.getUserState.query();
1111
};
1212

13+
getUserSSOProviders: IUserService['getUserSSOProviders'] = async () => {
14+
return lambdaClient.user.getUserSSOProviders.query();
15+
};
16+
1317
makeUserOnboarded = async () => {
1418
return lambdaClient.user.makeUserOnboarded.mutate();
1519
};

src/services/user/type.ts

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import type { AdapterAccount } from 'next-auth/adapters';
12
import { DeepPartial } from 'utility-types';
23

34
import { UserGuide, UserInitializationState, UserPreference } from '@/types/user';
@@ -9,6 +10,7 @@ export interface IUserService {
910
duration: number;
1011
updatedAt: string;
1112
}>;
13+
getUserSSOProviders: () => Promise<AdapterAccount[]>;
1214
getUserState: () => Promise<UserInitializationState>;
1315
resetUserSettings: () => Promise<any>;
1416
updateGuide: (guide: Partial<UserGuide>) => Promise<any>;

0 commit comments

Comments
 (0)