Merge branch 'master' into Permissions
This commit is contained in:
commit
c41fbac467
2
jslib
2
jslib
|
@ -1 +1 @@
|
|||
Subproject commit f9042408f44b299a7cdd1286490b70f5fd2db999
|
||||
Subproject commit cea09a22e533ef3598bb497ba0503c2fcd5b2dc1
|
|
@ -606,6 +606,9 @@
|
|||
"message": "WARNING",
|
||||
"description": "WARNING (should stay in capitalized letters if the language permits)"
|
||||
},
|
||||
"confirmVaultExport": {
|
||||
"message": "Confirm Vault Export"
|
||||
},
|
||||
"exportWarningDesc": {
|
||||
"message": "This export contains your vault data in an unencrypted format. You should not store or send the exported file over unsecure channels (such as email). Delete it immediately after you are done using it."
|
||||
},
|
||||
|
@ -1431,5 +1434,8 @@
|
|||
},
|
||||
"personalOwnershipSubmitError": {
|
||||
"message": "Due to an Enterprise Policy, you are restricted from saving items to your personal vault. Change the Ownership option to an organization and choose from available Collections."
|
||||
},
|
||||
"personalOwnershipPolicyInEffect": {
|
||||
"message": "An organization policy is affecting your ownership options."
|
||||
}
|
||||
}
|
||||
|
|
|
@ -115,9 +115,7 @@ export class NativeMessagingBackground {
|
|||
error = chrome.runtime.lastError.message;
|
||||
}
|
||||
|
||||
if (error === 'Specified native messaging host not found.' ||
|
||||
error === 'Access to the specified native messaging host is forbidden.' ||
|
||||
error === 'An unexpected error occurred') {
|
||||
if (error != null) {
|
||||
this.messagingService.send('showDialog', {
|
||||
text: this.i18nService.t('desktopIntegrationDisabledDesc'),
|
||||
title: this.i18nService.t('desktopIntegrationDisabledTitle'),
|
||||
|
@ -145,7 +143,7 @@ export class NativeMessagingBackground {
|
|||
message.timestamp = Date.now();
|
||||
|
||||
const encrypted = await this.cryptoService.encrypt(JSON.stringify(message), this.sharedSecret);
|
||||
this.port.postMessage({appId: this.appId, message: encrypted});
|
||||
this.postMessage({appId: this.appId, message: encrypted});
|
||||
}
|
||||
|
||||
getResponse(): Promise<any> {
|
||||
|
@ -154,6 +152,27 @@ export class NativeMessagingBackground {
|
|||
});
|
||||
}
|
||||
|
||||
private postMessage(message: any) {
|
||||
// Wrap in try-catch to when the port disconnected without triggering `onDisconnect`.
|
||||
try {
|
||||
this.port.postMessage(message);
|
||||
} catch (e) {
|
||||
// tslint:disable-next-line
|
||||
console.error("NativeMessaging port disconnected, disconnecting.");
|
||||
|
||||
this.sharedSecret = null;
|
||||
this.privateKey = null;
|
||||
this.connected = false;
|
||||
|
||||
this.messagingService.send('showDialog', {
|
||||
text: this.i18nService.t('nativeMessagingInvalidEncryptionDesc'),
|
||||
title: this.i18nService.t('nativeMessagingInvalidEncryptionTitle'),
|
||||
confirmText: this.i18nService.t('ok'),
|
||||
type: 'error',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private async onMessage(rawMessage: any) {
|
||||
const message = JSON.parse(await this.cryptoService.decryptToUtf8(rawMessage, this.sharedSecret));
|
||||
|
||||
|
@ -231,7 +250,7 @@ export class NativeMessagingBackground {
|
|||
|
||||
message.timestamp = Date.now();
|
||||
|
||||
this.port.postMessage({appId: this.appId, message: message});
|
||||
this.postMessage({appId: this.appId, message: message});
|
||||
}
|
||||
|
||||
private async showFingerprintDialog() {
|
||||
|
|
|
@ -25,12 +25,20 @@ export class SafariApp {
|
|||
return new Promise((resolve) => {
|
||||
const now = new Date();
|
||||
const messageId = now.getTime().toString() + '_' + Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);
|
||||
(window as any).webkit.messageHandlers.bitwardenApp.postMessage(JSON.stringify({
|
||||
id: messageId,
|
||||
command: command,
|
||||
data: data,
|
||||
responseData: null,
|
||||
}));
|
||||
if (typeof safari === typeof undefined) {
|
||||
(window as any).webkit.messageHandlers.bitwardenApp.postMessage(JSON.stringify({
|
||||
id: messageId,
|
||||
command: command,
|
||||
data: data,
|
||||
responseData: null,
|
||||
}));
|
||||
} else {
|
||||
safari.extension.dispatchMessage('bitwarden', {
|
||||
command: command,
|
||||
data: data,
|
||||
responseData: null,
|
||||
});
|
||||
}
|
||||
if (resolveNow) {
|
||||
resolve();
|
||||
} else {
|
||||
|
|
|
@ -3,6 +3,15 @@ window.addEventListener('message', (event) => {
|
|||
return;
|
||||
|
||||
if (event.data.command && (event.data.command === 'authResult')) {
|
||||
if (typeof chrome === typeof undefined) {
|
||||
safari.extension.dispatchMessage('bitwarden', {
|
||||
command: event.data.command,
|
||||
code: event.data.code,
|
||||
state: event.data.state,
|
||||
referrer: event.source.location.hostname,
|
||||
});
|
||||
return;
|
||||
}
|
||||
chrome.runtime.sendMessage({
|
||||
command: event.data.command,
|
||||
code: event.data.code,
|
||||
|
|
|
@ -41,11 +41,11 @@ export class SsoComponent extends BaseSsoComponent {
|
|||
this.redirectUri = url + '/sso-connector.html';
|
||||
this.clientId = 'browser';
|
||||
|
||||
super.onSuccessfulLogin = () => {
|
||||
super.onSuccessfulLogin = async () => {
|
||||
await syncService.fullSync(true);
|
||||
BrowserApi.reloadOpenWindows();
|
||||
const thisWindow = window.open('', '_self');
|
||||
thisWindow.close();
|
||||
return syncService.fullSync(true);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@ export class ActionButtonsComponent {
|
|||
}
|
||||
|
||||
async copy(cipher: CipherView, value: string, typeI18nKey: string, aType: string) {
|
||||
if (value == null || !this.displayTotpCopyButton(cipher)) {
|
||||
if (value == null || aType === 'TOTP' && !this.displayTotpCopyButton(cipher)) {
|
||||
return;
|
||||
} else if (value === cipher.login.totp) {
|
||||
value = await this.totpService.getCode(value);
|
||||
|
|
|
@ -41,13 +41,6 @@
|
|||
</div>
|
||||
<div class="box-footer">
|
||||
<p>{{'exportMasterPassword' | i18n}}</p>
|
||||
<strong>{{'warning' | i18n}}</strong>:
|
||||
<span *ngIf="!encryptedFormat">
|
||||
{{'exportWarningDesc' | i18n}}
|
||||
</span>
|
||||
<span *ngIf="encryptedFormat">
|
||||
{{'encExportWarningDesc' | i18n}}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</content>
|
||||
|
|
|
@ -14,6 +14,9 @@
|
|||
</div>
|
||||
</header>
|
||||
<content *ngIf="cipher">
|
||||
<app-callout type="info" *ngIf="allowOwnershipOptions() && !allowPersonal">
|
||||
{{'personalOwnershipPolicyInEffect' | i18n}}
|
||||
</app-callout>
|
||||
<div class="box">
|
||||
<div class="box-header">
|
||||
{{'itemInformation' | i18n}}
|
||||
|
|
|
@ -16,14 +16,10 @@ class SafariExtensionViewController: SFSafariExtensionViewController, WKScriptMe
|
|||
if initedWebView {
|
||||
return
|
||||
}
|
||||
let version = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String
|
||||
initedWebView = true
|
||||
let parentHeight = SafariExtensionViewController.shared.preferredContentSize.height
|
||||
let parentWidth = SafariExtensionViewController.shared.preferredContentSize.width
|
||||
let webViewConfig = WKWebViewConfiguration()
|
||||
let bundleURL = Bundle.main.resourceURL!.absoluteURL
|
||||
let html = bundleURL.appendingPathComponent("app/popup/index.html")
|
||||
let url = URL(string: "\(html.absoluteString)?appVersion=\(version!)")
|
||||
webViewConfig.preferences.setValue(true, forKey: "allowFileAccessFromFileURLs")
|
||||
webViewConfig.preferences.setValue(true, forKey: "developerExtrasEnabled")
|
||||
webViewConfig.userContentController.add(self, name: "bitwardenApp")
|
||||
|
@ -31,12 +27,26 @@ class SafariExtensionViewController: SFSafariExtensionViewController, WKScriptMe
|
|||
configuration: webViewConfig)
|
||||
webView.navigationDelegate = self
|
||||
webView.allowsLinkPreview = false
|
||||
webView.loadFileURL(url!, allowingReadAccessTo: bundleURL)
|
||||
navigateWebView("app/popup/index.html")
|
||||
webView.alphaValue = 0.0
|
||||
webView.uiDelegate = self
|
||||
view.addSubview(webView)
|
||||
}
|
||||
|
||||
func navigateWebView(_ relativeUrl: String){
|
||||
let version = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String
|
||||
let bundleUrl = Bundle.main.resourceURL!.absoluteURL
|
||||
|
||||
if var urlComponents = URLComponents(string: bundleUrl.absoluteString + relativeUrl) {
|
||||
if (urlComponents.queryItems?.first(where: { $0.name == "appVersion" })?.value == nil) {
|
||||
urlComponents.queryItems = urlComponents.queryItems ?? []
|
||||
urlComponents.queryItems!.append(URLQueryItem(name: "appVersion", value: version))
|
||||
}
|
||||
|
||||
webView.loadFileURL(urlComponents.url!, allowingReadAccessTo: bundleUrl)
|
||||
}
|
||||
}
|
||||
|
||||
func webView(_ webView: WKWebView, didFinish _: WKNavigation!) {
|
||||
if #available(OSXApplicationExtension 10.12, *) {
|
||||
NSAnimationContext.runAnimationGroup({ _ in
|
||||
|
@ -179,6 +189,14 @@ class SafariExtensionViewController: SFSafariExtensionViewController, WKScriptMe
|
|||
replyMessage(message: m)
|
||||
} else if command == "createNewTab" {
|
||||
if let data = m.data, let url = URL(string: data) {
|
||||
if !data.starts(with: "https://") && !data.starts(with: "http://") {
|
||||
SFSafariApplication.getActiveWindow { win in
|
||||
win?.getToolbarItem(completionHandler: { item in
|
||||
item?.showPopover()
|
||||
self.navigateWebView("app/" + url.absoluteString)
|
||||
})
|
||||
}
|
||||
}
|
||||
SFSafariApplication.getActiveWindow { win in
|
||||
win?.openTab(with: url, makeActiveIfPossible: true, completionHandler: { _ in
|
||||
// Tab opened
|
||||
|
|
|
@ -254,7 +254,7 @@ export default class AutofillService implements AutofillServiceInterface {
|
|||
}
|
||||
}
|
||||
|
||||
const autoFillResponse = await this.doAutoFill({
|
||||
const totpCode = await this.doAutoFill({
|
||||
cipher: cipher,
|
||||
pageDetails: pageDetails,
|
||||
skipTotp: !fromCommand,
|
||||
|
@ -265,12 +265,12 @@ export default class AutofillService implements AutofillServiceInterface {
|
|||
fillNewPassword: fromCommand,
|
||||
});
|
||||
|
||||
// Only update last used index if doAutoFill didn't throw an exception
|
||||
// Update last used index as autofill has succeed
|
||||
if (fromCommand) {
|
||||
this.cipherService.updateLastUsedIndexForUrl(tab.url);
|
||||
}
|
||||
|
||||
return autoFillResponse;
|
||||
return totpCode;
|
||||
}
|
||||
|
||||
// Helpers
|
||||
|
|
Loading…
Reference in New Issue