Submodule jslib contains modified content
diff --git a/jslib/angular/src/components/register.component.ts b/jslib/angular/src/components/register.component.ts
index fd91af29..abcfd62c 100644
--- a/jslib/angular/src/components/register.component.ts
+++ b/jslib/angular/src/components/register.component.ts
@@ -30,7 +30,7 @@ export class RegisterComponent extends CaptchaProtectedComponent implements OnIn
formPromise: Promise;
masterPasswordScore: number;
referenceData: ReferenceEventRequest;
- showTerms = true;
+ showTerms = false;
acceptPolicies: boolean = false;
protected successRoute = 'login';
@@ -43,7 +43,7 @@ export class RegisterComponent extends CaptchaProtectedComponent implements OnIn
protected passwordGenerationService: PasswordGenerationService, environmentService: EnvironmentService,
protected logService: LogService) {
super(environmentService, i18nService, platformUtilsService);
- this.showTerms = !platformUtilsService.isSelfHost();
+ this.showTerms = false;
}
async ngOnInit() {
@@ -81,6 +81,12 @@ export class RegisterComponent extends CaptchaProtectedComponent implements OnIn
}
async submit() {
+ if (typeof crypto.subtle === 'undefined') {
+ this.platformUtilsService.showToast('error', "This browser requires HTTPS to use the web vault",
+ "Check the Vaultwarden wiki for details on how to enable it");
+ return;
+ }
+
if (!this.acceptPolicies && this.showTerms) {
this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'),
this.i18nService.t('acceptPoliciesError'));
diff --git a/jslib/angular/src/components/sso.component.ts b/jslib/angular/src/components/sso.component.ts
index 1ab8e2f4..7e74fbd7 100644
--- a/jslib/angular/src/components/sso.component.ts
+++ b/jslib/angular/src/components/sso.component.ts
@@ -23,6 +23,8 @@ import { Utils } from 'jslib-common/misc/utils';
import { AuthResult } from 'jslib-common/models/domain/authResult';
+import { switchMap } from 'rxjs/operators';
+
@Directive()
export class SsoComponent {
identifier: string;
@@ -54,13 +56,19 @@ export class SsoComponent {
async ngOnInit() {
this.route.queryParams.pipe(first()).subscribe(async qParams => {
- if (qParams.code != null && qParams.state != null) {
+ // I have no idea why the qParams is empty here - I've hacked in an alternative very messily, but it works.
+ const workingParams = (new URL(window.location.href)).searchParams;
+ const workingSwap = {
+ code: workingParams.get('code'),
+ state: workingParams.get('state'),
+ };
+ if (workingSwap.code != null && workingSwap.state != null) {
const codeVerifier = await this.storageService.get(ConstantsService.ssoCodeVerifierKey);
const state = await this.storageService.get(ConstantsService.ssoStateKey);
await this.storageService.remove(ConstantsService.ssoCodeVerifierKey);
await this.storageService.remove(ConstantsService.ssoStateKey);
- if (qParams.code != null && codeVerifier != null && state != null && this.checkState(state, qParams.state)) {
- await this.logIn(qParams.code, codeVerifier, this.getOrgIdentifierFromState(qParams.state));
+ if (workingSwap.code != null && codeVerifier != null && state != null && this.checkState(state, workingSwap.state)) {
+ await this.logIn(workingSwap.code, codeVerifier, this.getOrgIdentifierFromState(workingSwap.state));
}
} else if (qParams.clientId != null && qParams.redirectUri != null && qParams.state != null &&
qParams.codeChallenge != null) {
@@ -125,7 +133,7 @@ export class SsoComponent {
let authorizeUrl = this.environmentService.getIdentityUrl() + '/connect/authorize?' +
'client_id=' + this.clientId + '&redirect_uri=' + encodeURIComponent(this.redirectUri) + '&' +
'response_type=code&scope=api offline_access&' +
- 'state=' + state + '&code_challenge=' + codeChallenge + '&' +
+ 'state=' + encodeURIComponent(state) + '&code_challenge=' + codeChallenge + '&' +
'code_challenge_method=S256&response_mode=query&' +
'domain_hint=' + encodeURIComponent(this.identifier);
diff --git a/jslib/common/src/abstractions/api.service.ts b/jslib/common/src/abstractions/api.service.ts
index 1c6aa0ef..aab45eeb 100644
--- a/jslib/common/src/abstractions/api.service.ts
+++ b/jslib/common/src/abstractions/api.service.ts
@@ -38,6 +38,7 @@ import { OrganizationSsoRequest } from '../models/request/organization/organizat
import { OrganizationCreateRequest } from '../models/request/organizationCreateRequest';
import { OrganizationImportRequest } from '../models/request/organizationImportRequest';
import { OrganizationKeysRequest } from '../models/request/organizationKeysRequest';
+import { OrganizationSsoUpdateRequest } from '../models/request/organizationSsoUpdateRequest';
import { OrganizationSubscriptionUpdateRequest } from '../models/request/organizationSubscriptionUpdateRequest';
import { OrganizationTaxInfoUpdateRequest } from '../models/request/organizationTaxInfoUpdateRequest';
import { OrganizationUpdateRequest } from '../models/request/organizationUpdateRequest';
@@ -148,6 +149,7 @@ import { SendAccessResponse } from '../models/response/sendAccessResponse';
import { SendFileDownloadDataResponse } from '../models/response/sendFileDownloadDataResponse';
import { SendFileUploadDataResponse } from '../models/response/sendFileUploadDataResponse';
import { SendResponse } from '../models/response/sendResponse';
+import { SsoConfigResponse } from '../models/response/ssoConfigResponse';
import { SubscriptionResponse } from '../models/response/subscriptionResponse';
import { SyncResponse } from '../models/response/syncResponse';
import { TaxInfoResponse } from '../models/response/taxInfoResponse';
@@ -386,6 +388,8 @@ export abstract class ApiService {
getOrganizationSso: (id: string) => Promise;
postOrganization: (request: OrganizationCreateRequest) => Promise;
putOrganization: (id: string, request: OrganizationUpdateRequest) => Promise;
+ getSsoConfig: (id: string) => Promise;
+ putOrganizationSso: (id: string, request: OrganizationSsoUpdateRequest) => Promise;
putOrganizationTaxInfo: (id: string, request: OrganizationTaxInfoUpdateRequest) => Promise;
postLeaveOrganization: (id: string) => Promise;
postOrganizationLicense: (data: FormData) => Promise;
diff --git a/jslib/common/src/models/request/organizationSsoUpdateRequest.ts b/jslib/common/src/models/request/organizationSsoUpdateRequest.ts
new file mode 100644
index 00000000..7075aecc
--- /dev/null
+++ b/jslib/common/src/models/request/organizationSsoUpdateRequest.ts
@@ -0,0 +1,8 @@
+export class OrganizationSsoUpdateRequest {
+ useSso: boolean;
+ callbackPath: string;
+ signedOutCallbackPath: string;
+ authority: string;
+ clientId: string;
+ clientSecret: string;
+}
diff --git a/jslib/common/src/models/request/tokenRequest.ts b/jslib/common/src/models/request/tokenRequest.ts
index 41797eb0..26206356 100644
--- a/jslib/common/src/models/request/tokenRequest.ts
+++ b/jslib/common/src/models/request/tokenRequest.ts
@@ -14,9 +14,10 @@ export class TokenRequest implements CaptchaProtectedRequest {
clientId: string;
clientSecret: string;
device?: DeviceRequest;
+ orgId?: string
constructor(credentials: string[], codes: string[], clientIdClientSecret: string[], public provider: TwoFactorProviderType,
- public token: string, public remember: boolean, public captchaResponse: string, device?: DeviceRequest) {
+ public token: string, public remember: boolean, public captchaResponse: string, device?: DeviceRequest, orgId?: string) {
if (credentials != null && credentials.length > 1) {
this.email = credentials[0];
this.masterPasswordHash = credentials[1];
@@ -28,6 +29,9 @@ export class TokenRequest implements CaptchaProtectedRequest {
this.clientId = clientIdClientSecret[0];
this.clientSecret = clientIdClientSecret[1];
}
+ if (orgId && orgId !== '') {
+ this.orgId = orgId;
+ }
this.device = device != null ? device : null;
}
@@ -50,6 +54,7 @@ export class TokenRequest implements CaptchaProtectedRequest {
obj.code = this.code;
obj.code_verifier = this.codeVerifier;
obj.redirect_uri = this.redirectUri;
+ obj.org_identifier = this.orgId;
} else {
throw new Error('must provide credentials or codes');
}
diff --git a/jslib/common/src/models/response/ssoConfigResponse.ts b/jslib/common/src/models/response/ssoConfigResponse.ts
new file mode 100644
index 00000000..9c72dd33
--- /dev/null
+++ b/jslib/common/src/models/response/ssoConfigResponse.ts
@@ -0,0 +1,22 @@
+import { BaseResponse } from './baseResponse';
+
+export class SsoConfigResponse extends BaseResponse {
+ id: string;
+ useSso: boolean;
+ callbackPath: string;
+ signedOutCallbackPath: string;
+ authority: string;
+ clientId: string;
+ clientSecret: string;
+
+ constructor(response: any) {
+ super(response);
+ this.id = this.getResponseProperty('Id');
+ this.useSso = this.getResponseProperty('UseSso');
+ this.callbackPath = this.getResponseProperty('CallbackPath');
+ this.signedOutCallbackPath = this.getResponseProperty('SignedOutCallbackPath');
+ this.authority = this.getResponseProperty('Authority');
+ this.clientId = this.getResponseProperty('ClientId');
+ this.clientSecret = this.getResponseProperty('ClientSecret');
+ }
+}
diff --git a/jslib/common/src/services/api.service.ts b/jslib/common/src/services/api.service.ts
index 46fdc139..16140f6c 100644
--- a/jslib/common/src/services/api.service.ts
+++ b/jslib/common/src/services/api.service.ts
@@ -39,6 +39,7 @@ import { OrganizationSsoRequest } from '../models/request/organization/organizat
import { OrganizationCreateRequest } from '../models/request/organizationCreateRequest';
import { OrganizationImportRequest } from '../models/request/organizationImportRequest';
import { OrganizationKeysRequest } from '../models/request/organizationKeysRequest';
+import { OrganizationSsoUpdateRequest } from '../models/request/organizationSsoUpdateRequest';
import { OrganizationSubscriptionUpdateRequest } from '../models/request/organizationSubscriptionUpdateRequest';
import { OrganizationTaxInfoUpdateRequest } from '../models/request/organizationTaxInfoUpdateRequest';
import { OrganizationUpdateRequest } from '../models/request/organizationUpdateRequest';
@@ -154,6 +155,7 @@ import { SendAccessResponse } from '../models/response/sendAccessResponse';
import { SendFileDownloadDataResponse } from '../models/response/sendFileDownloadDataResponse';
import { SendFileUploadDataResponse } from '../models/response/sendFileUploadDataResponse';
import { SendResponse } from '../models/response/sendResponse';
+import { SsoConfigResponse } from '../models/response/ssoConfigResponse';
import { SubscriptionResponse } from '../models/response/subscriptionResponse';
import { SyncResponse } from '../models/response/syncResponse';
import { TaxInfoResponse } from '../models/response/taxInfoResponse';
@@ -1187,6 +1189,16 @@ export class ApiService implements ApiServiceAbstraction {
return new OrganizationResponse(r);
}
+ async getSsoConfig(id: string): Promise {
+ const r = await this.send('GET', '/organizations/' + id + '/sso', null, true, true);
+ return new SsoConfigResponse(r);
+ }
+
+ async putOrganizationSso(id: string, request: OrganizationSsoUpdateRequest): Promise {
+ const r = await this.send('PUT', '/organizations/' + id + '/sso', request, true, false);
+ return new SsoConfigResponse(r);
+ }
+
async putOrganizationTaxInfo(id: string, request: OrganizationTaxInfoUpdateRequest): Promise {
return this.send('PUT', '/organizations/' + id + '/tax', request, true, false);
}
diff --git a/jslib/common/src/services/auth.service.ts b/jslib/common/src/services/auth.service.ts
index e4f670d7..d96f78cd 100644
--- a/jslib/common/src/services/auth.service.ts
+++ b/jslib/common/src/services/auth.service.ts
@@ -310,13 +310,13 @@ export class AuthService implements AuthServiceAbstraction {
let request: TokenRequest;
if (twoFactorToken != null && twoFactorProvider != null) {
request = new TokenRequest(emailPassword, codeCodeVerifier, clientIdClientSecret, twoFactorProvider,
- twoFactorToken, remember, captchaToken, deviceRequest);
+ twoFactorToken, remember, captchaToken, deviceRequest, orgId);
} else if (storedTwoFactorToken != null) {
request = new TokenRequest(emailPassword, codeCodeVerifier, clientIdClientSecret,
- TwoFactorProviderType.Remember, storedTwoFactorToken, false, captchaToken, deviceRequest);
+ TwoFactorProviderType.Remember, storedTwoFactorToken, false, captchaToken, deviceRequest, orgId);
} else {
request = new TokenRequest(emailPassword, codeCodeVerifier, clientIdClientSecret, null,
- null, false, captchaToken, deviceRequest);
+ null, false, captchaToken, deviceRequest, orgId);
}
const response = await this.apiService.postIdentityToken(request);
diff --git a/src/404.html b/src/404.html
index eba36375..cb8883ec 100644
--- a/src/404.html
+++ b/src/404.html
@@ -41,10 +41,10 @@
You can return to the web vault, check our status page
- or contact us.
+ or contact us.