refactor(server): handle ConnectedAccount on user model (#10030)

This commit is contained in:
fengmk2
2025-02-09 08:31:02 +00:00
parent 18513c6e55
commit 09b5eb60eb
2 changed files with 93 additions and 2 deletions

View File

@@ -297,3 +297,49 @@ test('should paginate users', async t => {
Array.from({ length: 10 }).map((_, i) => `test${i}@affine.pro`) Array.from({ length: 10 }).map((_, i) => `test${i}@affine.pro`)
); );
}); });
// #region ConnectedAccount
test('should create, get, update, delete connected account', async t => {
const user = await t.context.user.create({
email: 'test@affine.pro',
});
const connectedAccount = await t.context.user.createConnectedAccount({
userId: user.id,
provider: 'test-provider',
providerAccountId: 'test-provider-account-id',
accessToken: 'test-access-token',
});
t.truthy(connectedAccount);
const connectedAccount2 = await t.context.user.getConnectedAccount(
connectedAccount.provider,
connectedAccount.providerAccountId
);
t.truthy(connectedAccount2);
t.is(connectedAccount2!.id, connectedAccount.id);
t.is(connectedAccount2!.user.id, user.id);
const updatedConnectedAccount = await t.context.user.updateConnectedAccount(
connectedAccount.id,
{
accessToken: 'new-access-token',
}
);
t.is(updatedConnectedAccount.accessToken, 'new-access-token');
// get the updated connected account
const connectedAccount3 = await t.context.user.getConnectedAccount(
connectedAccount.provider,
connectedAccount.providerAccountId
);
t.is(connectedAccount3!.accessToken, 'new-access-token');
await t.context.user.deleteConnectedAccount(connectedAccount.id);
const connectedAccount4 = await t.context.user.getConnectedAccount(
connectedAccount.provider,
connectedAccount.providerAccountId
);
t.is(connectedAccount4, null);
});
// #endregion

View File

@@ -1,5 +1,5 @@
import { Injectable } from '@nestjs/common'; import { Injectable } from '@nestjs/common';
import { Prisma, type User } from '@prisma/client'; import { type ConnectedAccount, Prisma, type User } from '@prisma/client';
import { pick } from 'lodash-es'; import { pick } from 'lodash-es';
import { import {
@@ -21,6 +21,15 @@ const publicUserSelect = {
type CreateUserInput = Omit<Prisma.UserCreateInput, 'name'> & { name?: string }; type CreateUserInput = Omit<Prisma.UserCreateInput, 'name'> & { name?: string };
type UpdateUserInput = Omit<Partial<Prisma.UserCreateInput>, 'id'>; type UpdateUserInput = Omit<Partial<Prisma.UserCreateInput>, 'id'>;
type CreateConnectedAccountInput = Omit<
Prisma.ConnectedAccountUncheckedCreateInput,
'id'
> & { accessToken: string };
type UpdateConnectedAccountInput = Omit<
Prisma.ConnectedAccountUncheckedUpdateInput,
'id'
>;
declare global { declare global {
interface Events { interface Events {
'user.created': User; 'user.created': User;
@@ -35,7 +44,7 @@ declare global {
} }
export type PublicUser = Pick<User, keyof typeof publicUserSelect>; export type PublicUser = Pick<User, keyof typeof publicUserSelect>;
export type { User }; export type { ConnectedAccount, User };
@Injectable() @Injectable()
export class UserModel extends BaseModel { export class UserModel extends BaseModel {
@@ -228,4 +237,40 @@ export class UserModel extends BaseModel {
async count() { async count() {
return this.db.user.count(); return this.db.user.count();
} }
// #region ConnectedAccount
async createConnectedAccount(data: CreateConnectedAccountInput) {
return await this.db.connectedAccount.create({
data,
});
}
async getConnectedAccount(provider: string, providerAccountId: string) {
return await this.db.connectedAccount.findFirst({
where: { provider, providerAccountId },
include: {
user: true,
},
});
}
async updateConnectedAccount(id: string, data: UpdateConnectedAccountInput) {
return await this.db.connectedAccount.update({
where: { id },
data,
});
}
async deleteConnectedAccount(id: string) {
const { count } = await this.db.connectedAccount.deleteMany({
where: { id },
});
if (count > 0) {
this.logger.log(`Deleted connected account ${id}`);
}
return count;
}
// #endregion
} }