From 5a7042364bd3c158256dbd55851e42b9ef2bc0da Mon Sep 17 00:00:00 2001 From: Jason Rasmussen Date: Fri, 5 Sep 2025 17:59:11 -0400 Subject: [PATCH] feat: add partner create endpoint (#21625) --- e2e/src/api/specs/partner.e2e-spec.ts | 4 +- e2e/src/utils.ts | 3 +- .../repositories/partner_api.repository.dart | 4 +- mobile/openapi/README.md | Bin 40360 -> 40647 bytes mobile/openapi/lib/api.dart | Bin 14498 -> 14536 bytes mobile/openapi/lib/api/deprecated_api.dart | Bin 2315 -> 4091 bytes mobile/openapi/lib/api/partners_api.dart | Bin 7031 -> 8919 bytes mobile/openapi/lib/api_client.dart | Bin 36070 -> 36154 bytes .../openapi/lib/model/partner_create_dto.dart | Bin 0 -> 2904 bytes ...rtner_dto.dart => partner_update_dto.dart} | Bin 2876 -> 2876 bytes open-api/immich-openapi-specs.json | 91 +++++++++++++--- open-api/typescript-sdk/src/fetch-client.ts | 30 ++++-- .../controllers/partner.controller.spec.ts | 101 ++++++++++++++++++ server/src/controllers/partner.controller.ts | 18 +++- server/src/dtos/partner.dto.ts | 9 +- server/src/services/partner.service.spec.ts | 4 +- server/src/services/partner.service.ts | 6 +- .../partner-settings.svelte | 4 +- 18 files changed, 233 insertions(+), 41 deletions(-) create mode 100644 mobile/openapi/lib/model/partner_create_dto.dart rename mobile/openapi/lib/model/{update_partner_dto.dart => partner_update_dto.dart} (66%) create mode 100644 server/src/controllers/partner.controller.spec.ts diff --git a/e2e/src/api/specs/partner.e2e-spec.ts b/e2e/src/api/specs/partner.e2e-spec.ts index db37791ba..9047a9705 100644 --- a/e2e/src/api/specs/partner.e2e-spec.ts +++ b/e2e/src/api/specs/partner.e2e-spec.ts @@ -23,8 +23,8 @@ describe('/partners', () => { ]); await Promise.all([ - createPartner({ id: user2.userId }, { headers: asBearerAuth(user1.accessToken) }), - createPartner({ id: user1.userId }, { headers: asBearerAuth(user2.accessToken) }), + createPartner({ partnerCreateDto: { sharedWithId: user2.userId } }, { headers: asBearerAuth(user1.accessToken) }), + createPartner({ partnerCreateDto: { sharedWithId: user1.userId } }, { headers: asBearerAuth(user2.accessToken) }), ]); }); diff --git a/e2e/src/utils.ts b/e2e/src/utils.ts index 3ac374f16..b33d6cb19 100644 --- a/e2e/src/utils.ts +++ b/e2e/src/utils.ts @@ -462,7 +462,8 @@ export const utils = { updateLibrary: (accessToken: string, id: string, dto: UpdateLibraryDto) => updateLibrary({ id, updateLibraryDto: dto }, { headers: asBearerAuth(accessToken) }), - createPartner: (accessToken: string, id: string) => createPartner({ id }, { headers: asBearerAuth(accessToken) }), + createPartner: (accessToken: string, id: string) => + createPartner({ partnerCreateDto: { sharedWithId: id } }, { headers: asBearerAuth(accessToken) }), updateMyPreferences: (accessToken: string, userPreferencesUpdateDto: UserPreferencesUpdateDto) => updateMyPreferences({ userPreferencesUpdateDto }, { headers: asBearerAuth(accessToken) }), diff --git a/mobile/lib/repositories/partner_api.repository.dart b/mobile/lib/repositories/partner_api.repository.dart index 82554d62e..d497da4d4 100644 --- a/mobile/lib/repositories/partner_api.repository.dart +++ b/mobile/lib/repositories/partner_api.repository.dart @@ -22,14 +22,14 @@ class PartnerApiRepository extends ApiRepository { } Future create(String id) async { - final dto = await checkNull(_api.createPartner(id)); + final dto = await checkNull(_api.createPartnerDeprecated(id)); return UserConverter.fromPartnerDto(dto); } Future delete(String id) => _api.removePartner(id); Future update(String id, {required bool inTimeline}) async { - final dto = await checkNull(_api.updatePartner(id, UpdatePartnerDto(inTimeline: inTimeline))); + final dto = await checkNull(_api.updatePartner(id, PartnerUpdateDto(inTimeline: inTimeline))); return UserConverter.fromPartnerDto(dto); } } diff --git a/mobile/openapi/README.md b/mobile/openapi/README.md index 863e6e01a650bce5aefc5d2d2d2b5a41dc29054e..6cd26aefc48c5e7029312be909c5e5979a02d0d4 100644 GIT binary patch delta 223 zcmZ3no9XyorVaPxJd%r26H8J95{pXmQj1(t3yM;cf&3ILtyqne{A7K7gpgxFre1D} zGDJfGL_-Q(!{m8}3Y$;Ky%L%%Y$QH8$B>r`p>y(FBMEUF`ZmuqRB{)02D`$gBp+%k r)IF0OtAr=-sz{NA*cMul0(2Xus{NG`ll?0>HfvYzl-n#aV+tz(Hq)$ diff --git a/mobile/openapi/lib/api.dart b/mobile/openapi/lib/api.dart index a197f17fa7f881c8b80edfd13030cd2e15b9c53c..e87c160d96a179743ba27710790696f95d9eb422 100644 GIT binary patch delta 36 scmZ2fc%pE_ZK=sdN^+AgOZl-S7M0|s7EPWgt+rWR`iA&sRpVM#03WFiEdT%j delta 41 xcmX?6xTtW$ZK=tO(r%L{Nb_y3mcAg)U67Jkk{Vx-SX7cXIYCcqvzKulD*$J65AFZ} diff --git a/mobile/openapi/lib/api/deprecated_api.dart b/mobile/openapi/lib/api/deprecated_api.dart index f9a496b990dfea3e7be9192e8ee3ad91f41723f7..cdcd27750df1c44c6e3631c76021321fff72b96f 100644 GIT binary patch delta 449 zcmeAc`YpfV8Y7d5;p7{P3Va2LMJ0KuMS96asfi`2lk-@mCd)8|B?gxiW#*;FDrBZ8 zXcVOumSz^Erf6DmDJZy=mXsEy+61K*7v$#^r`jn%GzLJ7aY-#GN=*hDloFm_muUJ*p ziSaVfubWNS?lH0#r2+#iPhoO6hvMY9Yzihi3hJ14tAhhZ0aL;n93Ye5a>z^;XD!?; I!}OjF0FsQIYXATM delta 12 Tcmew@-z~J^8sp|;9H#65CA9?n diff --git a/mobile/openapi/lib/api/partners_api.dart b/mobile/openapi/lib/api/partners_api.dart index eb5d5f580697cf2e02bcd4ae65172a2cc215c3c7..a5fdf53ab56279e1952b81c7ff93bfd7b14eba0d 100644 GIT binary patch delta 602 zcmexvcHMP@2a{4jVo^z6YLRnMYGO&MOG$pLLIIk{#oSK- delta 259 zcmcca`rT}U2h-#PPV>n-rFb{5U2*K$fuzRPO3 znTJ=3Up}-TC9xzmAhD<}BtKT66j@|)A*pFCMkbF!z~9=61ylDyQS$&9iP;Y4Z8%`EOVCYz^J H2MGcINSYJV delta 59 zcmdlri|N@+rVRmZlb5({ojl)zb@L{7GZU_Yl*E$MfW)GbyvZM`rFanB)S}6ba>|>Z IR|g9M0Q`d(o&W#< diff --git a/mobile/openapi/lib/model/partner_create_dto.dart b/mobile/openapi/lib/model/partner_create_dto.dart new file mode 100644 index 0000000000000000000000000000000000000000..09d60c5c772cf91e65f7eb72ca37a8ad48878df6 GIT binary patch literal 2904 zcmbVOZExE)5dQ98aVdsa0aSV0ry{An7L7BcYvZEzHVlR#FcM|4lSz%FY8a{i`|e0d zmSwleR-mm#-Rtu_chqP!7>(fd@AKL7U#EA|kFV#`Yq+_6Hx1!>26wYLyq{g)-u!ij zW@Py)W!jE^j(&PEphvNiO7l2VI?hDFFQJl^;c3hZzUI<~&9hjSO52kjtk|%viOb5y zn*UP?jqZ}I@!yhZ{NHkIFt|3S-4i8^WzxnX#e^agTswDjGFc%cH*ull3e9ZJWc=dC zILVndg8`K{=FIul7blnAMl;z`i1c?pluq5n3ZC;&~{U~^$2gVpf#Phs=hG{pD23#$0vDpIrL9ibvKG#HX(7ufMK z1X&d*8`8)|7$?*YL8ayy&Wal|T_q?i6O-g(oH{F#7zZ?0DG}xmjzs>8tHFU-gX(K* z5Ut9UW+@F-;0g@kS)aOR$Tnp-1$^84WJ|sSDq^$C_k?VZ44`)yC4z~dWa z@BlrZ^1%)JN~;aKFL1ITV};@2uEE43qPeLGOHw@wzF6)-rI3Uvl>z7HPKS{&cgjxJ zrQJ3$5og>hK^P1Xhm>0d*mogvm&VD z26oK*UDTc3*t7C2S>w8>Z{tfSn~O8Xy9=*qx{CcuJzx+|^|s+Kq9?&k(+#2NJ9?Z; z7btRe9cCWk6oFcJ$G`cOR-^Oxn%q;_PZ9~yeN+%RSDmoq`rwe*@QX3&WZB8+1S2f>A^?$VUL|HsVV)ahz z?0`oVgnb>7+-D*pidyJ8LJHe4-4ATos_VqGW2%lQMljEL%YXZYg;Fzk2Q#F(LTTJ{ t!28W$S{efeZ$HiM=tHe$-(7m`=h<)M+m80+!NGBO!@KXbs{!tme*t~bu>Sx6 literal 0 HcmV?d00001 diff --git a/mobile/openapi/lib/model/update_partner_dto.dart b/mobile/openapi/lib/model/partner_update_dto.dart similarity index 66% rename from mobile/openapi/lib/model/update_partner_dto.dart rename to mobile/openapi/lib/model/partner_update_dto.dart index 3af3c83ad10bdc89ff568e2811ca015b658bd811..25cf2177642a2e2f07a355b3eab386c7a326f54f 100644 GIT binary patch delta 383 zcmdlZwnuD(I%9A^Vo^z6YEfuGN@7W>OG&;$HJ5^dzP`RfP-;nOQC_h^qC#G3xk5C$ zx>$wGyyB9?yyR3ppavA#$yJP#cu_?pnYN;d+-BO3CbFD)I+}<#iy4|oA4@!%$S;-( zG?9AN05p+1teI#cL2PT$M0nV(&_sgS_o0c%ajZiVxyfORCZfz4hbGd;c>+x&nd>G1 DM^umE delta 383 zcmdlZwnuD(I%9BXK}uptYCvL9NnUD^OG&;$HJ5^dzP`RfP-;nOQC_h^qC#G3xk5C$ zx>$wGyyB9?yyR3ppavA#$yJP#cu_?pnYN;d+-BO3CbFD)I+}<#iy4|oA4@!%$S;-( zG?9AN05p+1teI#cL2PT$M0nV(&_sgS_o0c%ajZiVxyfORCZfz4hbGd;c>+x&nd>G1 DKFg2d diff --git a/open-api/immich-openapi-specs.json b/open-api/immich-openapi-specs.json index e148e7efa..5a7886253 100644 --- a/open-api/immich-openapi-specs.json +++ b/open-api/immich-openapi-specs.json @@ -4994,6 +4994,48 @@ ], "x-immich-permission": "partner.read", "description": "This endpoint requires the `partner.read` permission." + }, + "post": { + "operationId": "createPartner", + "parameters": [], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PartnerCreateDto" + } + } + }, + "required": true + }, + "responses": { + "201": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PartnerResponseDto" + } + } + }, + "description": "" + } + }, + "security": [ + { + "bearer": [] + }, + { + "cookie": [] + }, + { + "api_key": [] + } + ], + "tags": [ + "Partners" + ], + "x-immich-permission": "partner.create", + "description": "This endpoint requires the `partner.create` permission." } }, "/partners/{id}": { @@ -5033,7 +5075,9 @@ "description": "This endpoint requires the `partner.delete` permission." }, "post": { - "operationId": "createPartner", + "deprecated": true, + "description": "This property was deprecated in v1.141.0. This endpoint requires the `partner.create` permission.", + "operationId": "createPartnerDeprecated", "parameters": [ { "name": "id", @@ -5069,10 +5113,13 @@ } ], "tags": [ - "Partners" + "Partners", + "Deprecated" ], - "x-immich-permission": "partner.create", - "description": "This endpoint requires the `partner.create` permission." + "x-immich-lifecycle": { + "deprecatedAt": "v1.141.0" + }, + "x-immich-permission": "partner.create" }, "put": { "operationId": "updatePartner", @@ -5091,7 +5138,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdatePartnerDto" + "$ref": "#/components/schemas/PartnerUpdateDto" } } }, @@ -12853,6 +12900,18 @@ ], "type": "object" }, + "PartnerCreateDto": { + "properties": { + "sharedWithId": { + "format": "uuid", + "type": "string" + } + }, + "required": [ + "sharedWithId" + ], + "type": "object" + }, "PartnerDirection": { "enum": [ "shared-by", @@ -12899,6 +12958,17 @@ ], "type": "object" }, + "PartnerUpdateDto": { + "properties": { + "inTimeline": { + "type": "boolean" + } + }, + "required": [ + "inTimeline" + ], + "type": "object" + }, "PeopleResponse": { "properties": { "enabled": { @@ -17241,17 +17311,6 @@ }, "type": "object" }, - "UpdatePartnerDto": { - "properties": { - "inTimeline": { - "type": "boolean" - } - }, - "required": [ - "inTimeline" - ], - "type": "object" - }, "UsageByUserDto": { "properties": { "photos": { diff --git a/open-api/typescript-sdk/src/fetch-client.ts b/open-api/typescript-sdk/src/fetch-client.ts index c642dc93a..a74afd733 100644 --- a/open-api/typescript-sdk/src/fetch-client.ts +++ b/open-api/typescript-sdk/src/fetch-client.ts @@ -811,7 +811,10 @@ export type PartnerResponseDto = { profileChangedAt: string; profileImagePath: string; }; -export type UpdatePartnerDto = { +export type PartnerCreateDto = { + sharedWithId: string; +}; +export type PartnerUpdateDto = { inTimeline: boolean; }; export type PeopleResponseDto = { @@ -3122,6 +3125,21 @@ export function getPartners({ direction }: { ...opts })); } +/** + * This endpoint requires the `partner.create` permission. + */ +export function createPartner({ partnerCreateDto }: { + partnerCreateDto: PartnerCreateDto; +}, opts?: Oazapfts.RequestOpts) { + return oazapfts.ok(oazapfts.fetchJson<{ + status: 201; + data: PartnerResponseDto; + }>("/partners", oazapfts.json({ + ...opts, + method: "POST", + body: partnerCreateDto + }))); +} /** * This endpoint requires the `partner.delete` permission. */ @@ -3134,9 +3152,9 @@ export function removePartner({ id }: { })); } /** - * This endpoint requires the `partner.create` permission. + * This property was deprecated in v1.141.0. This endpoint requires the `partner.create` permission. */ -export function createPartner({ id }: { +export function createPartnerDeprecated({ id }: { id: string; }, opts?: Oazapfts.RequestOpts) { return oazapfts.ok(oazapfts.fetchJson<{ @@ -3150,9 +3168,9 @@ export function createPartner({ id }: { /** * This endpoint requires the `partner.update` permission. */ -export function updatePartner({ id, updatePartnerDto }: { +export function updatePartner({ id, partnerUpdateDto }: { id: string; - updatePartnerDto: UpdatePartnerDto; + partnerUpdateDto: PartnerUpdateDto; }, opts?: Oazapfts.RequestOpts) { return oazapfts.ok(oazapfts.fetchJson<{ status: 200; @@ -3160,7 +3178,7 @@ export function updatePartner({ id, updatePartnerDto }: { }>(`/partners/${encodeURIComponent(id)}`, oazapfts.json({ ...opts, method: "PUT", - body: updatePartnerDto + body: partnerUpdateDto }))); } /** diff --git a/server/src/controllers/partner.controller.spec.ts b/server/src/controllers/partner.controller.spec.ts new file mode 100644 index 000000000..2c507a634 --- /dev/null +++ b/server/src/controllers/partner.controller.spec.ts @@ -0,0 +1,101 @@ +import { PartnerController } from 'src/controllers/partner.controller'; +import { LoggingRepository } from 'src/repositories/logging.repository'; +import { PartnerService } from 'src/services/partner.service'; +import request from 'supertest'; +import { errorDto } from 'test/medium/responses'; +import { factory } from 'test/small.factory'; +import { automock, ControllerContext, controllerSetup, mockBaseService } from 'test/utils'; + +describe(PartnerController.name, () => { + let ctx: ControllerContext; + const service = mockBaseService(PartnerService); + + beforeAll(async () => { + ctx = await controllerSetup(PartnerController, [ + { provide: PartnerService, useValue: service }, + { provide: LoggingRepository, useValue: automock(LoggingRepository, { strict: false }) }, + ]); + return () => ctx.close(); + }); + + beforeEach(() => { + service.resetAllMocks(); + ctx.reset(); + }); + + describe('GET /partners', () => { + it('should be an authenticated route', async () => { + await request(ctx.getHttpServer()).get('/partners'); + expect(ctx.authenticate).toHaveBeenCalled(); + }); + + it(`should require a direction`, async () => { + const { status, body } = await request(ctx.getHttpServer()).get(`/partners`).set('Authorization', `Bearer token`); + expect(status).toBe(400); + expect(body).toEqual( + errorDto.badRequest([ + 'direction should not be empty', + expect.stringContaining('direction must be one of the following values:'), + ]), + ); + }); + + it(`should require direction to be an enum`, async () => { + const { status, body } = await request(ctx.getHttpServer()) + .get(`/partners`) + .query({ direction: 'invalid' }) + .set('Authorization', `Bearer token`); + expect(status).toBe(400); + expect(body).toEqual( + errorDto.badRequest([expect.stringContaining('direction must be one of the following values:')]), + ); + }); + }); + + describe('POST /partners', () => { + it('should be an authenticated route', async () => { + await request(ctx.getHttpServer()).post('/partners'); + expect(ctx.authenticate).toHaveBeenCalled(); + }); + + it(`should require sharedWithId to be a uuid`, async () => { + const { status, body } = await request(ctx.getHttpServer()) + .post(`/partners`) + .send({ sharedWithId: 'invalid' }) + .set('Authorization', `Bearer token`); + expect(status).toBe(400); + expect(body).toEqual(errorDto.badRequest([expect.stringContaining('must be a UUID')])); + }); + }); + + describe('PUT /partners/:id', () => { + it('should be an authenticated route', async () => { + await request(ctx.getHttpServer()).put(`/partners/${factory.uuid()}`); + expect(ctx.authenticate).toHaveBeenCalled(); + }); + + it(`should require id to be a uuid`, async () => { + const { status, body } = await request(ctx.getHttpServer()) + .put(`/partners/invalid`) + .send({ inTimeline: true }) + .set('Authorization', `Bearer token`); + expect(status).toBe(400); + expect(body).toEqual(errorDto.badRequest([expect.stringContaining('must be a UUID')])); + }); + }); + + describe('DELETE /partners/:id', () => { + it('should be an authenticated route', async () => { + await request(ctx.getHttpServer()).delete(`/partners/${factory.uuid()}`); + expect(ctx.authenticate).toHaveBeenCalled(); + }); + + it(`should require id to be a uuid`, async () => { + const { status, body } = await request(ctx.getHttpServer()) + .delete(`/partners/invalid`) + .set('Authorization', `Bearer token`); + expect(status).toBe(400); + expect(body).toEqual(errorDto.badRequest([expect.stringContaining('must be a UUID')])); + }); + }); +}); diff --git a/server/src/controllers/partner.controller.ts b/server/src/controllers/partner.controller.ts index f2f4e3d7d..7cb5c1c27 100644 --- a/server/src/controllers/partner.controller.ts +++ b/server/src/controllers/partner.controller.ts @@ -1,7 +1,8 @@ import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Param, Post, Put, Query } from '@nestjs/common'; import { ApiTags } from '@nestjs/swagger'; +import { EndpointLifecycle } from 'src/decorators'; import { AuthDto } from 'src/dtos/auth.dto'; -import { PartnerResponseDto, PartnerSearchDto, UpdatePartnerDto } from 'src/dtos/partner.dto'; +import { PartnerCreateDto, PartnerResponseDto, PartnerSearchDto, PartnerUpdateDto } from 'src/dtos/partner.dto'; import { Permission } from 'src/enum'; import { Auth, Authenticated } from 'src/middleware/auth.guard'; import { PartnerService } from 'src/services/partner.service'; @@ -18,10 +19,17 @@ export class PartnerController { return this.service.search(auth, dto); } - @Post(':id') + @Post() @Authenticated({ permission: Permission.PartnerCreate }) - createPartner(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise { - return this.service.create(auth, id); + createPartner(@Auth() auth: AuthDto, @Body() dto: PartnerCreateDto): Promise { + return this.service.create(auth, dto); + } + + @Post(':id') + @EndpointLifecycle({ deprecatedAt: 'v1.141.0' }) + @Authenticated({ permission: Permission.PartnerCreate }) + createPartnerDeprecated(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise { + return this.service.create(auth, { sharedWithId: id }); } @Put(':id') @@ -29,7 +37,7 @@ export class PartnerController { updatePartner( @Auth() auth: AuthDto, @Param() { id }: UUIDParamDto, - @Body() dto: UpdatePartnerDto, + @Body() dto: PartnerUpdateDto, ): Promise { return this.service.update(auth, id, dto); } diff --git a/server/src/dtos/partner.dto.ts b/server/src/dtos/partner.dto.ts index 28d4adf8b..599213f66 100644 --- a/server/src/dtos/partner.dto.ts +++ b/server/src/dtos/partner.dto.ts @@ -1,9 +1,14 @@ import { IsNotEmpty } from 'class-validator'; import { UserResponseDto } from 'src/dtos/user.dto'; import { PartnerDirection } from 'src/repositories/partner.repository'; -import { ValidateEnum } from 'src/validation'; +import { ValidateEnum, ValidateUUID } from 'src/validation'; -export class UpdatePartnerDto { +export class PartnerCreateDto { + @ValidateUUID() + sharedWithId!: string; +} + +export class PartnerUpdateDto { @IsNotEmpty() inTimeline!: boolean; } diff --git a/server/src/services/partner.service.spec.ts b/server/src/services/partner.service.spec.ts index c6d5762c2..db057a453 100644 --- a/server/src/services/partner.service.spec.ts +++ b/server/src/services/partner.service.spec.ts @@ -53,7 +53,7 @@ describe(PartnerService.name, () => { mocks.partner.get.mockResolvedValue(void 0); mocks.partner.create.mockResolvedValue(partner); - await expect(sut.create(auth, user2.id)).resolves.toBeDefined(); + await expect(sut.create(auth, { sharedWithId: user2.id })).resolves.toBeDefined(); expect(mocks.partner.create).toHaveBeenCalledWith({ sharedById: partner.sharedById, @@ -69,7 +69,7 @@ describe(PartnerService.name, () => { mocks.partner.get.mockResolvedValue(partner); - await expect(sut.create(auth, user2.id)).rejects.toBeInstanceOf(BadRequestException); + await expect(sut.create(auth, { sharedWithId: user2.id })).rejects.toBeInstanceOf(BadRequestException); expect(mocks.partner.create).not.toHaveBeenCalled(); }); diff --git a/server/src/services/partner.service.ts b/server/src/services/partner.service.ts index 755b68839..628efa9d4 100644 --- a/server/src/services/partner.service.ts +++ b/server/src/services/partner.service.ts @@ -1,7 +1,7 @@ import { BadRequestException, Injectable } from '@nestjs/common'; import { Partner } from 'src/database'; import { AuthDto } from 'src/dtos/auth.dto'; -import { PartnerResponseDto, PartnerSearchDto, UpdatePartnerDto } from 'src/dtos/partner.dto'; +import { PartnerCreateDto, PartnerResponseDto, PartnerSearchDto, PartnerUpdateDto } from 'src/dtos/partner.dto'; import { mapUser } from 'src/dtos/user.dto'; import { Permission } from 'src/enum'; import { PartnerDirection, PartnerIds } from 'src/repositories/partner.repository'; @@ -9,7 +9,7 @@ import { BaseService } from 'src/services/base.service'; @Injectable() export class PartnerService extends BaseService { - async create(auth: AuthDto, sharedWithId: string): Promise { + async create(auth: AuthDto, { sharedWithId }: PartnerCreateDto): Promise { const partnerId: PartnerIds = { sharedById: auth.user.id, sharedWithId }; const exists = await this.partnerRepository.get(partnerId); if (exists) { @@ -39,7 +39,7 @@ export class PartnerService extends BaseService { .map((partner) => this.mapPartner(partner, direction)); } - async update(auth: AuthDto, sharedById: string, dto: UpdatePartnerDto): Promise { + async update(auth: AuthDto, sharedById: string, dto: PartnerUpdateDto): Promise { await this.requireAccess({ auth, permission: Permission.PartnerUpdate, ids: [sharedById] }); const partnerId: PartnerIds = { sharedById, sharedWithId: auth.user.id }; diff --git a/web/src/lib/components/user-settings-page/partner-settings.svelte b/web/src/lib/components/user-settings-page/partner-settings.svelte index 586cdf4af..e847ea201 100644 --- a/web/src/lib/components/user-settings-page/partner-settings.svelte +++ b/web/src/lib/components/user-settings-page/partner-settings.svelte @@ -104,7 +104,7 @@ try { for (const user of users) { - await createPartner({ id: user.id }); + await createPartner({ partnerCreateDto: { sharedWithId: user.id } }); } await refreshPartners(); @@ -115,7 +115,7 @@ const handleShowOnTimelineChanged = async (partner: PartnerSharing, inTimeline: boolean) => { try { - await updatePartner({ id: partner.user.id, updatePartnerDto: { inTimeline } }); + await updatePartner({ id: partner.user.id, partnerUpdateDto: { inTimeline } }); partner.inTimeline = inTimeline; } catch (error) {