accept org invite
This commit is contained in:
parent
8e3d5b99c5
commit
470a767eaf
2
jslib
2
jslib
|
@ -1 +1 @@
|
||||||
Subproject commit 67b2b5318556f2d21bf4f2d117af8228b9f9549c
|
Subproject commit 41dd6b1f2c2d12bfa23162fa4ff5200620b6e8ac
|
|
@ -0,0 +1,33 @@
|
||||||
|
<div class="mt-5 d-flex justify-content-center" *ngIf="loading">
|
||||||
|
<div>
|
||||||
|
<img src="../../images/logo-dark@2x.png" class="mb-4 logo" alt="Bitwarden">
|
||||||
|
<p class="text-center">
|
||||||
|
<i class="fa fa-spinner fa-spin fa-2x text-muted"></i>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="container" *ngIf="!loading && !authed">
|
||||||
|
<div class="row justify-content-md-center mt-5">
|
||||||
|
<div class="col-5">
|
||||||
|
<p class="lead text-center mb-4">{{'joinOrganization' | i18n}}</p>
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-body">
|
||||||
|
<p class="text-center">
|
||||||
|
{{orgName}}
|
||||||
|
<strong class="d-block mt-2">{{email}}</strong>
|
||||||
|
</p>
|
||||||
|
<p>{{'joinOrganizationDesc' | i18n}}</p>
|
||||||
|
<hr>
|
||||||
|
<div class="d-flex">
|
||||||
|
<a routerLink="/" class="btn btn-primary btn-block">
|
||||||
|
{{'logIn' | i18n}}
|
||||||
|
</a>
|
||||||
|
<a routerLink="/" class="btn btn-primary btn-block ml-2 mt-0">
|
||||||
|
{{'createAccount' | i18n}}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -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<any>;
|
||||||
|
|
||||||
|
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() {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
|
@ -25,7 +25,12 @@ export class VerifyEmailTokenComponent implements OnInit {
|
||||||
private apiService: ApiService, private userService: UserService) { }
|
private apiService: ApiService, private userService: UserService) { }
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
|
let fired = false;
|
||||||
this.route.queryParams.subscribe(async (qParams) => {
|
this.route.queryParams.subscribe(async (qParams) => {
|
||||||
|
if (fired) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fired = true;
|
||||||
if (qParams.userId != null && qParams.token != null) {
|
if (qParams.userId != null && qParams.token != null) {
|
||||||
try {
|
try {
|
||||||
await this.apiService.postAccountVerifyEmailToken(
|
await this.apiService.postAccountVerifyEmailToken(
|
||||||
|
|
|
@ -8,6 +8,7 @@ import { FrontendLayoutComponent } from './layouts/frontend-layout.component';
|
||||||
import { OrganizationLayoutComponent } from './layouts/organization-layout.component';
|
import { OrganizationLayoutComponent } from './layouts/organization-layout.component';
|
||||||
import { UserLayoutComponent } from './layouts/user-layout.component';
|
import { UserLayoutComponent } from './layouts/user-layout.component';
|
||||||
|
|
||||||
|
import { AcceptOrganizationComponent } from './accounts/accept-organization.component';
|
||||||
import { HintComponent } from './accounts/hint.component';
|
import { HintComponent } from './accounts/hint.component';
|
||||||
import { LockComponent } from './accounts/lock.component';
|
import { LockComponent } from './accounts/lock.component';
|
||||||
import { LoginComponent } from './accounts/login.component';
|
import { LoginComponent } from './accounts/login.component';
|
||||||
|
@ -72,6 +73,7 @@ const routes: Routes = [
|
||||||
},
|
},
|
||||||
{ path: 'lock', component: LockComponent },
|
{ path: 'lock', component: LockComponent },
|
||||||
{ path: 'verify-email', component: VerifyEmailTokenComponent },
|
{ path: 'verify-email', component: VerifyEmailTokenComponent },
|
||||||
|
{ path: 'accept-organization', component: AcceptOrganizationComponent },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -25,6 +25,7 @@ import { NavbarComponent } from './layouts/navbar.component';
|
||||||
import { OrganizationLayoutComponent } from './layouts/organization-layout.component';
|
import { OrganizationLayoutComponent } from './layouts/organization-layout.component';
|
||||||
import { UserLayoutComponent } from './layouts/user-layout.component';
|
import { UserLayoutComponent } from './layouts/user-layout.component';
|
||||||
|
|
||||||
|
import { AcceptOrganizationComponent } from './accounts/accept-organization.component';
|
||||||
import { HintComponent } from './accounts/hint.component';
|
import { HintComponent } from './accounts/hint.component';
|
||||||
import { LockComponent } from './accounts/lock.component';
|
import { LockComponent } from './accounts/lock.component';
|
||||||
import { LoginComponent } from './accounts/login.component';
|
import { LoginComponent } from './accounts/login.component';
|
||||||
|
@ -136,6 +137,7 @@ import { SearchPipe } from 'jslib/angular/pipes/search.pipe';
|
||||||
ToasterModule,
|
ToasterModule,
|
||||||
],
|
],
|
||||||
declarations: [
|
declarations: [
|
||||||
|
AcceptOrganizationComponent,
|
||||||
AccountComponent,
|
AccountComponent,
|
||||||
AddEditComponent,
|
AddEditComponent,
|
||||||
AdjustPaymentComponent,
|
AdjustPaymentComponent,
|
||||||
|
|
|
@ -2107,5 +2107,20 @@
|
||||||
},
|
},
|
||||||
"updateBrowserDesc": {
|
"updateBrowserDesc": {
|
||||||
"message": "You are using an unsupported web browser. The web vault may not function properly."
|
"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."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue