diff --git a/backend/core/src/main/java/org/opencdmp/errorcode/ErrorThesaurusProperties.java b/backend/core/src/main/java/org/opencdmp/errorcode/ErrorThesaurusProperties.java index 5a0fe404e..81311d920 100644 --- a/backend/core/src/main/java/org/opencdmp/errorcode/ErrorThesaurusProperties.java +++ b/backend/core/src/main/java/org/opencdmp/errorcode/ErrorThesaurusProperties.java @@ -544,4 +544,34 @@ public class ErrorThesaurusProperties { public ErrorDescription getUserProfileInactive() { return userProfileInactive; } public void setUserProfileInactive(ErrorDescription userProfileInactive) {this.userProfileInactive = userProfileInactive; } + + private ErrorDescription planInvitationAlreadyConfirmed; + + public ErrorDescription getPlanInvitationAlreadyConfirmed() { + return planInvitationAlreadyConfirmed; + } + + public void setPlanInvitationAlreadyConfirmed(ErrorDescription planInvitationAlreadyConfirmed) { + this.planInvitationAlreadyConfirmed = planInvitationAlreadyConfirmed; + } + + private ErrorDescription anotherUserToken; + + public ErrorDescription getAnotherUserToken() { + return anotherUserToken; + } + + public void setAnotherUserToken(ErrorDescription anotherUserToken) { + this.anotherUserToken = anotherUserToken; + } + + private ErrorDescription tokenNotExist; + + public ErrorDescription getTokenNotExist() { + return tokenNotExist; + } + + public void setTokenNotExist(ErrorDescription tokenNotExist) { + this.tokenNotExist = tokenNotExist; + } } diff --git a/backend/core/src/main/java/org/opencdmp/service/plan/PlanService.java b/backend/core/src/main/java/org/opencdmp/service/plan/PlanService.java index 2970494af..bf4cfbb60 100644 --- a/backend/core/src/main/java/org/opencdmp/service/plan/PlanService.java +++ b/backend/core/src/main/java/org/opencdmp/service/plan/PlanService.java @@ -52,7 +52,7 @@ public interface PlanService { void inviteUserOrAssignUsers(UUID id, List users) throws InvalidApplicationException, JAXBException, IOException; - void planInvitationAccept(String token) throws InvalidApplicationException, IOException; + UUID planInvitationAccept(String token) throws InvalidApplicationException, IOException; PlanImportExport exportXmlEntity(UUID id, boolean ignoreAuthorize, boolean isPublic) throws MyForbiddenException, MyNotFoundException, JAXBException, ParserConfigurationException, IOException, InstantiationException, IllegalAccessException, SAXException, InvalidApplicationException; diff --git a/backend/core/src/main/java/org/opencdmp/service/plan/PlanServiceImpl.java b/backend/core/src/main/java/org/opencdmp/service/plan/PlanServiceImpl.java index 769066c20..0b544757c 100644 --- a/backend/core/src/main/java/org/opencdmp/service/plan/PlanServiceImpl.java +++ b/backend/core/src/main/java/org/opencdmp/service/plan/PlanServiceImpl.java @@ -1979,21 +1979,28 @@ public class PlanServiceImpl implements PlanService { return persist.getToken(); } - public void planInvitationAccept(String token) throws InvalidApplicationException { + public UUID planInvitationAccept(String token) throws InvalidApplicationException { ActionConfirmationEntity action = this.queryFactory.query(ActionConfirmationQuery.class).tokens(token).types(ActionConfirmationType.PlanInvitation).isActive(IsActive.Active).first(); if (action == null){ - throw new MyApplicationException("Token does not exist!"); + throw new MyValidationException(this.errors.getTokenNotExist().getCode(), this.errors.getTokenNotExist().getMessage()); } if (action.getStatus().equals(ActionConfirmationStatus.Accepted)){ - throw new MyApplicationException("Invitation is already confirmed!"); + throw new MyValidationException(this.errors.getPlanInvitationAlreadyConfirmed().getCode(), this.errors.getPlanInvitationAlreadyConfirmed().getMessage()); } if (action.getExpiresAt().compareTo(Instant.now()) < 0){ - throw new MyApplicationException("Token has expired!"); + throw new MyValidationException(this.errors.getRequestHasExpired().getCode(), this.errors.getRequestHasExpired().getMessage()); } PlanInvitationEntity planInvitation = this.xmlHandlingService.fromXmlSafe(PlanInvitationEntity.class, action.getData()); + if (planInvitation == null) { + throw new MyApplicationException("plan invitation don't exist"); + } + UserContactInfoEntity contactInfoEntity = this.queryFactory.query(UserContactInfoQuery.class).disableTracking().userIds(this.userScope.getUserId()).values(planInvitation.getEmail()).types(ContactInfoType.Email).first(); + if (contactInfoEntity == null){ + throw new MyValidationException(this.errors.getAnotherUserToken().getCode(), this.errors.getAnotherUserToken().getMessage()); + } PlanUserEntity data = new PlanUserEntity(); data.setId(UUID.randomUUID()); data.setIsActive(IsActive.Active); @@ -2008,6 +2015,7 @@ public class PlanServiceImpl implements PlanService { this.entityManager.merge(action); this.annotationEntityTouchedIntegrationEventHandler.handlePlan(planInvitation.getPlanId()); + return planInvitation.getPlanId(); } //region Export diff --git a/backend/core/src/main/java/org/opencdmp/service/user/UserServiceImpl.java b/backend/core/src/main/java/org/opencdmp/service/user/UserServiceImpl.java index 7f36055f2..839310d47 100644 --- a/backend/core/src/main/java/org/opencdmp/service/user/UserServiceImpl.java +++ b/backend/core/src/main/java/org/opencdmp/service/user/UserServiceImpl.java @@ -1051,7 +1051,7 @@ public class UserServiceImpl implements UserService { this.entityManager.reloadTenantFilters(); } if (action == null) - throw new MyNotFoundException(this.messageSource.getMessage("General_ItemNotFound", new Object[]{token, ActionConfirmationEntity.class.getSimpleName()}, LocaleContextHolder.getLocale())); + throw new MyValidationException(this.errors.getTokenNotExist().getCode(), this.errors.getTokenNotExist().getMessage()); this.checkActionState(action, true); UserInviteToTenantRequestEntity userInviteToTenantRequest = this.xmlHandlingService.fromXmlSafe(UserInviteToTenantRequestEntity.class, action.getData()); diff --git a/backend/web/src/main/java/org/opencdmp/controllers/PlanController.java b/backend/web/src/main/java/org/opencdmp/controllers/PlanController.java index 6e0005f45..fb8dcde83 100644 --- a/backend/web/src/main/java/org/opencdmp/controllers/PlanController.java +++ b/backend/web/src/main/java/org/opencdmp/controllers/PlanController.java @@ -483,20 +483,20 @@ public class PlanController { return true; } - @GetMapping("{id}/token/{token}/invite-accept") - @OperationWithTenantHeader(summary = "Accept an invitation token for a plan by id") + @GetMapping("token/{token}/invite-accept") + @OperationWithTenantHeader(summary = "Accept an invitation token for a plan by token") @Transactional @Hidden - public boolean acceptInvitation(@PathVariable("id") UUID id, @PathVariable("token") String token) throws InvalidApplicationException, JAXBException, IOException { - logger.debug(new MapLogEntry("inviting users to plan").And("id", id)); + public UUID acceptInvitation(@PathVariable("token") String token) throws InvalidApplicationException, JAXBException, IOException { + logger.debug(new MapLogEntry("inviting users to plan").And("token", token)); - this.planService.planInvitationAccept(token); + UUID planId = this.planService.planInvitationAccept(token); this.auditService.track(AuditableAction.Plan_Invite_Accept, Map.ofEntries( new AbstractMap.SimpleEntry("token", token) )); - return true; + return planId; } @RequestMapping(method = RequestMethod.GET, value = "/xml/export/{id}", produces = "application/xml") diff --git a/backend/web/src/main/resources/config/errors.yml b/backend/web/src/main/resources/config/errors.yml index b16ac899d..0218edebd 100644 --- a/backend/web/src/main/resources/config/errors.yml +++ b/backend/web/src/main/resources/config/errors.yml @@ -169,4 +169,13 @@ error-thesaurus: message: Global role is missing userProfileInactive: code: 160 - message: User account has not been activated \ No newline at end of file + message: User account has not been activated + planInvitationAlreadyConfirmed: + code: 161 + message: Plan invitation already confirmed + anotherUserToken: + code: 162 + message: This token is for another user + tokenNotExist: + code: 163 + message: This token does not exist \ No newline at end of file diff --git a/frontend/src/app/core/common/enum/respone-error-code.ts b/frontend/src/app/core/common/enum/respone-error-code.ts index cea47da18..04ba167f8 100644 --- a/frontend/src/app/core/common/enum/respone-error-code.ts +++ b/frontend/src/app/core/common/enum/respone-error-code.ts @@ -56,6 +56,9 @@ export enum ResponseErrorCode { missingTenantRole = 158, missingGlobalRole = 159, userProfileInactive = 160, + planInvitationAlreadyConfirmed = 161, + anotherUserToken = 162, + tokenNotExist = 163, // Notification & Annotation Errors InvalidApiKey = 200, @@ -199,7 +202,13 @@ export class ResponseErrorCodeHelper { case ResponseErrorCode.missingGlobalRole: return language.instant("GENERAL.BACKEND-ERRORS.MISSING-GLOBAL-ROLE"); case ResponseErrorCode.userProfileInactive: - return language.instant("GENERAL.BACKEND-ERRORS.CANNOT-PERFORM-ACTION-ON-USER") + return language.instant("GENERAL.BACKEND-ERRORS.CANNOT-PERFORM-ACTION-ON-USER"); + case ResponseErrorCode.planInvitationAlreadyConfirmed: + return language.instant("GENERAL.BACKEND-ERRORS.PLAN-INVITATION-ALREADY-CONFIRMED"); + case ResponseErrorCode.anotherUserToken: + return language.instant("GENERAL.BACKEND-ERRORS.ANOTHER-USER-TOKEN"); + case ResponseErrorCode.tokenNotExist: + return language.instant("GENERAL.BACKEND-ERRORS.TOKEN-NOT-EXIST"); default: return language.instant("GENERAL.SNACK-BAR.NOT-FOUND"); } diff --git a/frontend/src/app/core/services/plan/plan.service.ts b/frontend/src/app/core/services/plan/plan.service.ts index 78cece372..825218f63 100644 --- a/frontend/src/app/core/services/plan/plan.service.ts +++ b/frontend/src/app/core/services/plan/plan.service.ts @@ -172,10 +172,10 @@ export class PlanService { catchError((error: any) => throwError(error))); } - acceptInvitation(PlanId: Guid, token: string): Observable { - const url = `${this.apiBase}/${PlanId}/token/${token}/invite-accept`; + acceptInvitation(token: string): Observable { + const url = `${this.apiBase}/token/${token}/invite-accept`; - return this.http.get(url).pipe(catchError((error: any) => throwError(error))); + return this.http.get(url).pipe(catchError((error: any) => throwError(error))); } downloadXML(id: Guid): Observable> { diff --git a/frontend/src/app/ui/plan/invitation/accepted/plan-invitation-accepted.component.html b/frontend/src/app/ui/plan/invitation/accepted/plan-invitation-accepted.component.html new file mode 100644 index 000000000..e69de29bb diff --git a/frontend/src/app/ui/plan/invitation/accepted/plan-invitation-accepted.component.ts b/frontend/src/app/ui/plan/invitation/accepted/plan-invitation-accepted.component.ts new file mode 100644 index 000000000..3a5f3acd4 --- /dev/null +++ b/frontend/src/app/ui/plan/invitation/accepted/plan-invitation-accepted.component.ts @@ -0,0 +1,63 @@ +import { HttpErrorResponse } from '@angular/common/http'; +import { Component, OnInit } from '@angular/core'; +import { ActivatedRoute, Router } from '@angular/router'; +import { AuthService } from '@app/core/services/auth/auth.service'; +import { SnackBarNotificationLevel } from '@app/core/services/notification/ui-notification-service'; +import { PlanService } from '@app/core/services/plan/plan.service'; +import { RouterUtilsService } from '@app/core/services/router/router-utils.service'; +import { BaseComponent } from '@common/base/base.component'; +import { HttpError, HttpErrorHandlingService } from '@common/modules/errors/error-handling/http-error-handling.service'; +import { takeUntil } from 'rxjs/operators'; + +@Component({ + selector: 'app-plan-invitation-accepted-component', + templateUrl: 'plan-invitation-accepted.component.html', + +}) +export class InvitationAcceptedComponent extends BaseComponent implements OnInit { + constructor( + private planService: PlanService, + private route: ActivatedRoute, + private router: Router, + private authentication: AuthService, + protected routerUtils: RouterUtilsService, + private httpErrorHandlingService: HttpErrorHandlingService + ) { super(); } + + ngOnInit(): void { + + this.route.params + .pipe(takeUntil(this._destroyed)) + .subscribe(params => { + const token = params['token']; + + if(this.isAuthenticated()){ + this.planService.acceptInvitation(token) + .pipe(takeUntil(this._destroyed)) + .subscribe(result => { + this.router.navigate([this.routerUtils.generateUrl('plans/edit/' + result)]); + }, + error => this.onCallbackError(error)); + }else{ + let returnUrl = `plans/invitation/${token}`; + this.router.navigate([this.routerUtils.generateUrl('login')], {queryParams:{returnUrl: this.routerUtils.generateUrl(returnUrl)}}); + } + }); + } + + + public isAuthenticated(): boolean { + return this.authentication.currentAccountIsAuthenticated(); + } + + onCallbackError(errorResponse: HttpErrorResponse) { + + this.httpErrorHandlingService.handleBackedRequestError(errorResponse, null, SnackBarNotificationLevel.Error) + + const error: HttpError = this.httpErrorHandlingService.getError(errorResponse); + if (error.statusCode === 302) { + this.router.navigate([this.routerUtils.generateUrl('home')]); + } + this.router.navigate([this.routerUtils.generateUrl('home')]); + } +} diff --git a/frontend/src/app/ui/plan/plan.module.ts b/frontend/src/app/ui/plan/plan.module.ts index 08abac917..cbb37bdcb 100644 --- a/frontend/src/app/ui/plan/plan.module.ts +++ b/frontend/src/app/ui/plan/plan.module.ts @@ -3,6 +3,7 @@ import { FormattingModule } from '@app/core/formatting.module'; import { PlanRoutingModule, PublicPlanRoutingModule } from '@app/ui/plan/plan.routing'; import { CommonFormsModule } from '@common/forms/common-forms.module'; import { CommonUiModule } from '@common/ui/common-ui.module'; +import { InvitationAcceptedComponent } from './invitation/accepted/plan-invitation-accepted.component'; @NgModule({ imports: [ @@ -12,6 +13,7 @@ import { CommonUiModule } from '@common/ui/common-ui.module'; PlanRoutingModule, ], declarations: [ + InvitationAcceptedComponent ], exports: [ ] diff --git a/frontend/src/app/ui/plan/plan.routing.ts b/frontend/src/app/ui/plan/plan.routing.ts index 08ce9f9ef..454fa91ce 100644 --- a/frontend/src/app/ui/plan/plan.routing.ts +++ b/frontend/src/app/ui/plan/plan.routing.ts @@ -2,6 +2,7 @@ import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; import { BreadcrumbService } from '../misc/breadcrumb/breadcrumb.service'; import { AuthGuard } from '@app/core/auth-guard.service'; +import { InvitationAcceptedComponent } from './invitation/accepted/plan-invitation-accepted.component'; const routes: Routes = [ { @@ -47,6 +48,7 @@ const routes: Routes = [ breadcrumb: true }, }, + { path: 'invitation/:token', component: InvitationAcceptedComponent }, ]; const publicRoutes: Routes = [ diff --git a/frontend/src/assets/i18n/de.json b/frontend/src/assets/i18n/de.json index f32703dd8..b584ec1ee 100644 --- a/frontend/src/assets/i18n/de.json +++ b/frontend/src/assets/i18n/de.json @@ -95,7 +95,10 @@ "PLAN-BLUEPRINT-IMPORT-DRAFT": "Plan Blueprint with code '{{planBlueprintCode}}' is not finalized yet.", "MISSING-TENANT-ROLE": "Υou must also select a tenant role", "MISSING-GLOBAL-ROLE": "Υou must also select a global role", - "CANNOT-PERFORM-ACTION-ON-USER": "Cannot perform action, user account has not been activated" + "CANNOT-PERFORM-ACTION-ON-USER": "Cannot perform action, user account has not been activated", + "PLAN-INVITATION-ALREADY-CONFIRMED": "Plan invitation has alreay confirmed", + "ANOTHER-USER-TOKEN": "This token is for another user", + "TOKEN-NOT-EXIST": "This token does not exist" }, "FORM-VALIDATION-DISPLAY-DIALOG": { "WARNING": "Warnung!", diff --git a/frontend/src/assets/i18n/en.json b/frontend/src/assets/i18n/en.json index 137e0edc3..1ed7efc5d 100644 --- a/frontend/src/assets/i18n/en.json +++ b/frontend/src/assets/i18n/en.json @@ -95,7 +95,10 @@ "PLAN-BLUEPRINT-IMPORT-DRAFT": "Plan Blueprint with code '{{planBlueprintCode}}' is not finalized yet.", "MISSING-TENANT-ROLE": "Υou must also select a tenant role", "MISSING-GLOBAL-ROLE": "Υou must also select a global role", - "CANNOT-PERFORM-ACTION-ON-USER": "Cannot perform action, user account has not been activated" + "CANNOT-PERFORM-ACTION-ON-USER": "Cannot perform action, user account has not been activated", + "PLAN-INVITATION-ALREADY-CONFIRMED": "Plan invitation has alreay confirmed", + "ANOTHER-USER-TOKEN": "This token is for another user", + "TOKEN-NOT-EXIST": "This token does not exist" }, "FORM-VALIDATION-DISPLAY-DIALOG": { "WARNING": "Warning!", diff --git a/frontend/src/assets/i18n/es.json b/frontend/src/assets/i18n/es.json index a148167cc..19ecda4c3 100644 --- a/frontend/src/assets/i18n/es.json +++ b/frontend/src/assets/i18n/es.json @@ -95,7 +95,10 @@ "PLAN-BLUEPRINT-IMPORT-DRAFT": "Plan Blueprint with code '{{planBlueprintCode}}' is not finalized yet.", "MISSING-TENANT-ROLE": "Υou must also select a tenant role", "MISSING-GLOBAL-ROLE": "Υou must also select a global role", - "CANNOT-PERFORM-ACTION-ON-USER": "Cannot perform action, user account has not been activated" + "CANNOT-PERFORM-ACTION-ON-USER": "Cannot perform action, user account has not been activated", + "PLAN-INVITATION-ALREADY-CONFIRMED": "Plan invitation has alreay confirmed", + "ANOTHER-USER-TOKEN": "This token is for another user", + "TOKEN-NOT-EXIST": "This token does not exist" }, "FORM-VALIDATION-DISPLAY-DIALOG": { "WARNING": "Atención!", diff --git a/frontend/src/assets/i18n/gr.json b/frontend/src/assets/i18n/gr.json index 6e3a74fc0..dd53b6313 100644 --- a/frontend/src/assets/i18n/gr.json +++ b/frontend/src/assets/i18n/gr.json @@ -95,7 +95,10 @@ "PLAN-BLUEPRINT-IMPORT-DRAFT": "Plan Blueprint with code '{{planBlueprintCode}}' is not finalized yet.", "MISSING-TENANT-ROLE": "Υou must also select a tenant role", "MISSING-GLOBAL-ROLE": "Υou must also select a global role", - "CANNOT-PERFORM-ACTION-ON-USER": "Cannot perform action, user account has not been activated" + "CANNOT-PERFORM-ACTION-ON-USER": "Cannot perform action, user account has not been activated", + "PLAN-INVITATION-ALREADY-CONFIRMED": "Plan invitation has alreay confirmed", + "ANOTHER-USER-TOKEN": "This token is for another user", + "TOKEN-NOT-EXIST": "This token does not exist" }, "FORM-VALIDATION-DISPLAY-DIALOG": { "WARNING": "Προσοχή!", diff --git a/frontend/src/assets/i18n/hr.json b/frontend/src/assets/i18n/hr.json index 17935d254..279ab9a90 100644 --- a/frontend/src/assets/i18n/hr.json +++ b/frontend/src/assets/i18n/hr.json @@ -95,7 +95,10 @@ "PLAN-BLUEPRINT-IMPORT-DRAFT": "Plan Blueprint with code '{{planBlueprintCode}}' is not finalized yet.", "MISSING-TENANT-ROLE": "Υou must also select a tenant role", "MISSING-GLOBAL-ROLE": "Υou must also select a global role", - "CANNOT-PERFORM-ACTION-ON-USER": "Cannot perform action, user account has not been activated" + "CANNOT-PERFORM-ACTION-ON-USER": "Cannot perform action, user account has not been activated", + "PLAN-INVITATION-ALREADY-CONFIRMED": "Plan invitation has alreay confirmed", + "ANOTHER-USER-TOKEN": "This token is for another user", + "TOKEN-NOT-EXIST": "This token does not exist" }, "FORM-VALIDATION-DISPLAY-DIALOG": { "WARNING": "Oprez!", diff --git a/frontend/src/assets/i18n/pl.json b/frontend/src/assets/i18n/pl.json index 5030528c4..439195cc0 100644 --- a/frontend/src/assets/i18n/pl.json +++ b/frontend/src/assets/i18n/pl.json @@ -95,7 +95,10 @@ "PLAN-BLUEPRINT-IMPORT-DRAFT": "Plan Blueprint with code '{{planBlueprintCode}}' is not finalized yet.", "MISSING-TENANT-ROLE": "Υou must also select a tenant role", "MISSING-GLOBAL-ROLE": "Υou must also select a global role", - "CANNOT-PERFORM-ACTION-ON-USER": "Cannot perform action, user account has not been activated" + "CANNOT-PERFORM-ACTION-ON-USER": "Cannot perform action, user account has not been activated", + "PLAN-INVITATION-ALREADY-CONFIRMED": "Plan invitation has alreay confirmed", + "ANOTHER-USER-TOKEN": "This token is for another user", + "TOKEN-NOT-EXIST": "This token does not exist" }, "FORM-VALIDATION-DISPLAY-DIALOG": { "WARNING": "Ostrzeżenie!", diff --git a/frontend/src/assets/i18n/pt.json b/frontend/src/assets/i18n/pt.json index fdc4d82ed..5a07a51d9 100644 --- a/frontend/src/assets/i18n/pt.json +++ b/frontend/src/assets/i18n/pt.json @@ -95,7 +95,10 @@ "PLAN-BLUEPRINT-IMPORT-DRAFT": "Plan Blueprint with code '{{planBlueprintCode}}' is not finalized yet.", "MISSING-TENANT-ROLE": "Υou must also select a tenant role", "MISSING-GLOBAL-ROLE": "Υou must also select a global role", - "CANNOT-PERFORM-ACTION-ON-USER": "Cannot perform action, user account has not been activated" + "CANNOT-PERFORM-ACTION-ON-USER": "Cannot perform action, user account has not been activated", + "PLAN-INVITATION-ALREADY-CONFIRMED": "Plan invitation has alreay confirmed", + "ANOTHER-USER-TOKEN": "This token is for another user", + "TOKEN-NOT-EXIST": "This token does not exist" }, "FORM-VALIDATION-DISPLAY-DIALOG": { "WARNING": "Atenção!", diff --git a/frontend/src/assets/i18n/sk.json b/frontend/src/assets/i18n/sk.json index f1eaadf44..1fef51062 100644 --- a/frontend/src/assets/i18n/sk.json +++ b/frontend/src/assets/i18n/sk.json @@ -95,7 +95,10 @@ "PLAN-BLUEPRINT-IMPORT-DRAFT": "Plan Blueprint with code '{{planBlueprintCode}}' is not finalized yet.", "MISSING-TENANT-ROLE": "Υou must also select a tenant role", "MISSING-GLOBAL-ROLE": "Υou must also select a global role", - "CANNOT-PERFORM-ACTION-ON-USER": "Cannot perform action, user account has not been activated" + "CANNOT-PERFORM-ACTION-ON-USER": "Cannot perform action, user account has not been activated", + "PLAN-INVITATION-ALREADY-CONFIRMED": "Plan invitation has alreay confirmed", + "ANOTHER-USER-TOKEN": "This token is for another user", + "TOKEN-NOT-EXIST": "This token does not exist" }, "FORM-VALIDATION-DISPLAY-DIALOG": { "WARNING": "Upozornenie!", diff --git a/frontend/src/assets/i18n/sr.json b/frontend/src/assets/i18n/sr.json index c589b8f6f..1409bc668 100644 --- a/frontend/src/assets/i18n/sr.json +++ b/frontend/src/assets/i18n/sr.json @@ -95,7 +95,10 @@ "PLAN-BLUEPRINT-IMPORT-DRAFT": "Plan Blueprint with code '{{planBlueprintCode}}' is not finalized yet.", "MISSING-TENANT-ROLE": "Υou must also select a tenant role", "MISSING-GLOBAL-ROLE": "Υou must also select a global role", - "CANNOT-PERFORM-ACTION-ON-USER": "Cannot perform action, user account has not been activated" + "CANNOT-PERFORM-ACTION-ON-USER": "Cannot perform action, user account has not been activated", + "PLAN-INVITATION-ALREADY-CONFIRMED": "Plan invitation has alreay confirmed", + "ANOTHER-USER-TOKEN": "This token is for another user", + "TOKEN-NOT-EXIST": "This token does not exist" }, "FORM-VALIDATION-DISPLAY-DIALOG": { "WARNING": "Oprez!", diff --git a/frontend/src/assets/i18n/tr.json b/frontend/src/assets/i18n/tr.json index 99d672fcb..94bd2f262 100644 --- a/frontend/src/assets/i18n/tr.json +++ b/frontend/src/assets/i18n/tr.json @@ -95,7 +95,10 @@ "PLAN-BLUEPRINT-IMPORT-DRAFT": "Plan Blueprint with code '{{planBlueprintCode}}' is not finalized yet.", "MISSING-TENANT-ROLE": "Υou must also select a tenant role", "MISSING-GLOBAL-ROLE": "Υou must also select a global role", - "CANNOT-PERFORM-ACTION-ON-USER": "Cannot perform action, user account has not been activated" + "CANNOT-PERFORM-ACTION-ON-USER": "Cannot perform action, user account has not been activated", + "PLAN-INVITATION-ALREADY-CONFIRMED": "Plan invitation has alreay confirmed", + "ANOTHER-USER-TOKEN": "This token is for another user", + "TOKEN-NOT-EXIST": "This token does not exist" }, "FORM-VALIDATION-DISPLAY-DIALOG": { "WARNING": "Uyarı!",