From 470a767eafe8578105b4ea7445003cade345beb3 Mon Sep 17 00:00:00 2001 From: Kyle Spearrin Date: Thu, 12 Jul 2018 16:05:42 -0400 Subject: [PATCH] accept org invite --- jslib | 2 +- .../accept-organization.component.html | 33 +++++++ .../accounts/accept-organization.component.ts | 88 +++++++++++++++++++ .../accounts/verify-email-token.component.ts | 5 ++ src/app/app-routing.module.ts | 2 + src/app/app.module.ts | 2 + src/locales/en/messages.json | 15 ++++ 7 files changed, 146 insertions(+), 1 deletion(-) create mode 100644 src/app/accounts/accept-organization.component.html create mode 100644 src/app/accounts/accept-organization.component.ts diff --git a/jslib b/jslib index 67b2b53185..41dd6b1f2c 160000 --- a/jslib +++ b/jslib @@ -1 +1 @@ -Subproject commit 67b2b5318556f2d21bf4f2d117af8228b9f9549c +Subproject commit 41dd6b1f2c2d12bfa23162fa4ff5200620b6e8ac diff --git a/src/app/accounts/accept-organization.component.html b/src/app/accounts/accept-organization.component.html new file mode 100644 index 0000000000..2a7c8b713a --- /dev/null +++ b/src/app/accounts/accept-organization.component.html @@ -0,0 +1,33 @@ +
+
+ +

+ +

+
+
+
+
+
+

{{'joinOrganization' | i18n}}

+
+
+

+ {{orgName}} + {{email}} +

+

{{'joinOrganizationDesc' | i18n}}

+
+ +
+
+
+
+
diff --git a/src/app/accounts/accept-organization.component.ts b/src/app/accounts/accept-organization.component.ts new file mode 100644 index 0000000000..265368b16d --- /dev/null +++ b/src/app/accounts/accept-organization.component.ts @@ -0,0 +1,88 @@ +import { + Component, + OnInit, +} from '@angular/core'; +import { + ActivatedRoute, + Router, + NavigationEnd, +} from '@angular/router'; + +import { + Toast, + ToasterService, +} from 'angular2-toaster'; + +import { ApiService } from 'jslib/abstractions/api.service'; +import { I18nService } from 'jslib/abstractions/i18n.service'; +import { UserService } from 'jslib/abstractions/user.service'; + +import { OrganizationUserAcceptRequest } from 'jslib/models/request/organizationUserAcceptRequest'; + +@Component({ + selector: 'app-accept-organization', + templateUrl: 'accept-organization.component.html', +}) +export class AcceptOrganizationComponent implements OnInit { + loading = true; + authed = false; + orgName: string; + email: string; + actionPromise: Promise; + + constructor(private router: Router, private toasterService: ToasterService, + private i18nService: I18nService, private route: ActivatedRoute, + private apiService: ApiService, private userService: UserService) { } + + ngOnInit() { + let fired = false; + this.route.queryParams.subscribe(async (qParams) => { + if (fired) { + return; + } + fired = true; + let error = qParams.organizationId == null || qParams.organizationUserId == null || + qParams.token == null; + if (!error) { + this.authed = await this.userService.isAuthenticated(); + if (this.authed) { + const request = new OrganizationUserAcceptRequest(); + request.token = qParams.token; + try { + this.actionPromise = this.apiService.postOrganizationUserAccept(qParams.organizationId, + qParams.organizationUserId, request); + await this.actionPromise; + const toast: Toast = { + type: 'success', + title: this.i18nService.t('inviteAccepted'), + body: this.i18nService.t('inviteAcceptedDesc'), + timeout: 10000, + }; + this.toasterService.popAsync(toast); + this.router.navigate(['/vault']); + } catch { + error = true; + } + } else { + this.email = qParams.email; + this.orgName = qParams.organizationName; + } + } + + if (error) { + this.toasterService.popAsync('error', null, this.i18nService.t('inviteAcceptFailed')); + this.router.navigate(['/']); + } + + this.loading = false; + }); + } + + login() { + // + } + + register() { + // + } +} diff --git a/src/app/accounts/verify-email-token.component.ts b/src/app/accounts/verify-email-token.component.ts index 91a819a713..d564009f98 100644 --- a/src/app/accounts/verify-email-token.component.ts +++ b/src/app/accounts/verify-email-token.component.ts @@ -25,7 +25,12 @@ export class VerifyEmailTokenComponent implements OnInit { private apiService: ApiService, private userService: UserService) { } ngOnInit() { + let fired = false; this.route.queryParams.subscribe(async (qParams) => { + if (fired) { + return; + } + fired = true; if (qParams.userId != null && qParams.token != null) { try { await this.apiService.postAccountVerifyEmailToken( diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index 94e91f87f8..d083e18e03 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -8,6 +8,7 @@ import { FrontendLayoutComponent } from './layouts/frontend-layout.component'; import { OrganizationLayoutComponent } from './layouts/organization-layout.component'; import { UserLayoutComponent } from './layouts/user-layout.component'; +import { AcceptOrganizationComponent } from './accounts/accept-organization.component'; import { HintComponent } from './accounts/hint.component'; import { LockComponent } from './accounts/lock.component'; import { LoginComponent } from './accounts/login.component'; @@ -72,6 +73,7 @@ const routes: Routes = [ }, { path: 'lock', component: LockComponent }, { path: 'verify-email', component: VerifyEmailTokenComponent }, + { path: 'accept-organization', component: AcceptOrganizationComponent }, ], }, { diff --git a/src/app/app.module.ts b/src/app/app.module.ts index b38e5f2948..e3f1c63f42 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -25,6 +25,7 @@ import { NavbarComponent } from './layouts/navbar.component'; import { OrganizationLayoutComponent } from './layouts/organization-layout.component'; import { UserLayoutComponent } from './layouts/user-layout.component'; +import { AcceptOrganizationComponent } from './accounts/accept-organization.component'; import { HintComponent } from './accounts/hint.component'; import { LockComponent } from './accounts/lock.component'; import { LoginComponent } from './accounts/login.component'; @@ -136,6 +137,7 @@ import { SearchPipe } from 'jslib/angular/pipes/search.pipe'; ToasterModule, ], declarations: [ + AcceptOrganizationComponent, AccountComponent, AddEditComponent, AdjustPaymentComponent, diff --git a/src/locales/en/messages.json b/src/locales/en/messages.json index f29c6fe43c..892c3f1e83 100644 --- a/src/locales/en/messages.json +++ b/src/locales/en/messages.json @@ -2107,5 +2107,20 @@ }, "updateBrowserDesc": { "message": "You are using an unsupported web browser. The web vault may not function properly." + }, + "joinOrganization": { + "message": "Join Organization" + }, + "joinOrganizationDesc": { + "message": "You've been invited to join the organization listed above. To accept the invitation, you need to log in or create a new Bitwarden account." + }, + "inviteAccepted": { + "message": "Invitation Accepted" + }, + "inviteAcceptedDesc": { + "message": "You can access this organization once an administrator confirms your membership. We'll send you an email when that happens." + }, + "inviteAcceptFailed": { + "message": "Unable to accept invitation. Ask an organization admin to send a new invitation." } }