Submodule jslib contains modified content
diff --git a/jslib/angular/src/components/register.component.ts b/jslib/angular/src/components/register.component.ts
index 53ec3c8..7b49db1 100644
--- a/jslib/angular/src/components/register.component.ts
+++ b/jslib/angular/src/components/register.component.ts
@@ -24,7 +24,7 @@ export class RegisterComponent {
     formPromise: Promise;
     masterPasswordScore: number;
     referenceData: ReferenceEventRequest;
-    showTerms = true;
+    showTerms = false;
     acceptPolicies: boolean = false;
 
     protected successRoute = 'login';
@@ -35,7 +35,7 @@ export class RegisterComponent {
         protected apiService: ApiService, protected stateService: StateService,
         protected platformUtilsService: PlatformUtilsService,
         protected passwordGenerationService: PasswordGenerationService) {
-        this.showTerms = !platformUtilsService.isSelfHost();
+        this.showTerms = false;
     }
 
     get masterPasswordScoreWidth() {
@@ -69,6 +69,12 @@ export class RegisterComponent {
     }
 
     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 d4512a1..ad57f69 100644
--- a/jslib/angular/src/components/sso.component.ts
+++ b/jslib/angular/src/components/sso.component.ts
@@ -19,6 +19,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;
@@ -48,13 +50,19 @@ export class SsoComponent {
 
     async ngOnInit() {
         const queryParamsSub = this.route.queryParams.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.getOrgIdentiferFromState(qParams.state));
+                if (workingSwap.code != null && codeVerifier != null && state != null && this.checkState(state, workingSwap.state)) {
+                    await this.logIn(workingSwap.code, codeVerifier, this.getOrgIdentiferFromState(workingSwap.state));
                 }
             } else if (qParams.clientId != null && qParams.redirectUri != null && qParams.state != null &&
                 qParams.codeChallenge != null) {
@@ -122,7 +130,7 @@ export class SsoComponent {
         let authorizeUrl = this.apiService.identityBaseUrl + '/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);
 
@@ -137,7 +145,7 @@ export class SsoComponent {
     private async logIn(code: string, codeVerifier: string, orgIdFromState: string) {
         this.loggingIn = true;
         try {
-            this.formPromise = this.authService.logInSso(code, codeVerifier, this.redirectUri);
+            this.formPromise = this.authService.logInSso(code, codeVerifier, this.redirectUri, orgIdFromState);
             const response = await this.formPromise;
             if (response.twoFactor) {
                 if (this.onSuccessfulLoginTwoFactorNavigate != null) {
diff --git a/jslib/common/src/abstractions/api.service.ts b/jslib/common/src/abstractions/api.service.ts
index 67131df..ce498ff 100644
--- a/jslib/common/src/abstractions/api.service.ts
+++ b/jslib/common/src/abstractions/api.service.ts
@@ -33,6 +33,7 @@ import { KeysRequest } from '../models/request/keysRequest';
 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 { OrganizationTaxInfoUpdateRequest } from '../models/request/organizationTaxInfoUpdateRequest';
 import { OrganizationUpdateRequest } from '../models/request/organizationUpdateRequest';
 import { OrganizationUpgradeRequest } from '../models/request/organizationUpgradeRequest';
@@ -122,6 +123,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';
@@ -360,6 +362,8 @@ export abstract class ApiService {
     getOrganizationTaxInfo: (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/abstractions/auth.service.ts b/jslib/common/src/abstractions/auth.service.ts
index ac7ef04..5b1b774 100644
--- a/jslib/common/src/abstractions/auth.service.ts
+++ b/jslib/common/src/abstractions/auth.service.ts
@@ -15,7 +15,7 @@ export abstract class AuthService {
     selectedTwoFactorProviderType: TwoFactorProviderType;
 
     logIn: (email: string, masterPassword: string) => Promise;
-    logInSso: (code: string, codeVerifier: string, redirectUrl: string) => Promise;
+    logInSso: (code: string, codeVerifier: string, redirectUrl: string, orgIdentifier: string) => Promise;
     logInApiKey: (clientId: string, clientSecret: string) => Promise;
     logInTwoFactor: (twoFactorProvider: TwoFactorProviderType, twoFactorToken: string,
         remember?: boolean) => Promise;
diff --git a/jslib/common/src/models/request/organizationSsoUpdateRequest.ts b/jslib/common/src/models/request/organizationSsoUpdateRequest.ts
new file mode 100644
index 0000000..7075aec
--- /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 7578012..964364f 100644
--- a/jslib/common/src/models/request/tokenRequest.ts
+++ b/jslib/common/src/models/request/tokenRequest.ts
@@ -14,9 +14,10 @@ export class TokenRequest {
     provider: TwoFactorProviderType;
     remember: boolean;
     device?: DeviceRequest;
+    orgIdentifier?: string;
 
     constructor(credentials: string[], codes: string[], clientIdClientSecret: string[], provider: TwoFactorProviderType,
-        token: string, remember: boolean, device?: DeviceRequest) {
+        token: string, remember: boolean, device?: DeviceRequest, orgIdentifier?: string) {
         if (credentials != null && credentials.length > 1) {
             this.email = credentials[0];
             this.masterPasswordHash = credentials[1];
@@ -28,6 +29,9 @@ export class TokenRequest {
             this.clientId = clientIdClientSecret[0];
             this.clientSecret = clientIdClientSecret[1];
         }
+        if (orgIdentifier && orgIdentifier !== '') {
+            this.orgIdentifier = orgIdentifier;
+        }
         this.token = token;
         this.provider = provider;
         this.remember = remember;
@@ -53,6 +57,7 @@ export class TokenRequest {
             obj.code = this.code;
             obj.code_verifier = this.codeVerifier;
             obj.redirect_uri = this.redirectUri;
+            obj.org_identifier = this.orgIdentifier;
         } else {
             throw new Error('must provide credentials or codes');
         }
diff --git a/jslib/common/src/services/api.service.ts b/jslib/common/src/services/api.service.ts
index 51c1c14..b615672 100644
--- a/jslib/common/src/services/api.service.ts
+++ b/jslib/common/src/services/api.service.ts
@@ -37,6 +37,7 @@ import { KeysRequest } from '../models/request/keysRequest';
 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 { OrganizationTaxInfoUpdateRequest } from '../models/request/organizationTaxInfoUpdateRequest';
 import { OrganizationUpdateRequest } from '../models/request/organizationUpdateRequest';
 import { OrganizationUpgradeRequest } from '../models/request/organizationUpgradeRequest';
@@ -128,6 +129,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';
@@ -1158,6 +1160,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 6536a94..6f4899c 100644
--- a/jslib/common/src/services/auth.service.ts
+++ b/jslib/common/src/services/auth.service.ts
@@ -130,10 +130,10 @@ export class AuthService implements AuthServiceAbstraction {
             key, null, null, null);
     }
 
-    async logInSso(code: string, codeVerifier: string, redirectUrl: string): Promise {
+    async logInSso(code: string, codeVerifier: string, redirectUrl: string, orgIdentifier: string): Promise {
         this.selectedTwoFactorProviderType = null;
         return await this.logInHelper(null, null, null, code, codeVerifier, redirectUrl, null, null,
-            null, null, null, null);
+            null, null, null, null, orgIdentifier);
     }
 
     async logInApiKey(clientId: string, clientSecret: string): Promise {
@@ -272,7 +272,7 @@ export class AuthService implements AuthServiceAbstraction {
 
     private async logInHelper(email: string, hashedPassword: string, localHashedPassword: string, code: string,
         codeVerifier: string, redirectUrl: string, clientId: string, clientSecret: string, key: SymmetricCryptoKey,
-        twoFactorProvider?: TwoFactorProviderType, twoFactorToken?: string, remember?: boolean): Promise {
+        twoFactorProvider?: TwoFactorProviderType, twoFactorToken?: string, remember?: boolean, orgIdentifier?: string): Promise {
         const storedTwoFactorToken = await this.tokenService.getTwoFactorToken(email);
         const appId = await this.appIdService.getAppId();
         const deviceRequest = new DeviceRequest(appId, this.platformUtilsService);
@@ -300,13 +300,13 @@ export class AuthService implements AuthServiceAbstraction {
         let request: TokenRequest;
         if (twoFactorToken != null && twoFactorProvider != null) {
             request = new TokenRequest(emailPassword, codeCodeVerifier, clientIdClientSecret, twoFactorProvider,
-                twoFactorToken, remember, deviceRequest);
+                twoFactorToken, remember, deviceRequest, orgIdentifier);
         } else if (storedTwoFactorToken != null) {
             request = new TokenRequest(emailPassword, codeCodeVerifier, clientIdClientSecret, TwoFactorProviderType.Remember,
-                storedTwoFactorToken, false, deviceRequest);
+                storedTwoFactorToken, false, deviceRequest, orgIdentifier);
         } else {
             request = new TokenRequest(emailPassword, codeCodeVerifier, clientIdClientSecret, null,
-                null, false, deviceRequest);
+                null, false, deviceRequest, orgIdentifier);
         }
 
         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.