mirror of
https://github.com/inverse-inc/sogo.git
synced 2026-05-12 23:15:26 +00:00
Initial Web-based management of email certificate
This commit is contained in:
@@ -76,6 +76,10 @@
|
||||
"Yes" = "Yes";
|
||||
"No" = "No";
|
||||
|
||||
/* generic messages */
|
||||
"Error" = "Error";
|
||||
"Success" = "Success";
|
||||
|
||||
/* alarms */
|
||||
"Reminder" = "Reminder";
|
||||
"Start" = "Start";
|
||||
|
||||
@@ -20,8 +20,20 @@
|
||||
|
||||
#import <Foundation/NSDictionary.h>
|
||||
|
||||
#import <NGHttp/NGHttpRequest.h>
|
||||
|
||||
#import <NGObjWeb/NSException+HTTP.h>
|
||||
#import <NGObjWeb/WOContext+SoObjects.h>
|
||||
#define COMPILING_NGOBJWEB 1 /* httpRequest is needed in importCertificateAction */
|
||||
#import <NGObjWeb/WORequest.h>
|
||||
#undef COMPILING_NGOBJWEB
|
||||
#import <NGObjWeb/WOResponse.h>
|
||||
|
||||
#import <NGMime/NGMimeBodyPart.h>
|
||||
#import <NGMime/NGMimeHeaderFields.h>
|
||||
#import <NGMime/NGMimeMultipartBody.h>
|
||||
#import <NGMime/NGMimeType.h>
|
||||
|
||||
#import <NGImap4/NSString+Imap4.h>
|
||||
#import <NGExtensions/NSString+misc.h>
|
||||
|
||||
@@ -91,7 +103,7 @@
|
||||
drafts = [[self clientObject] draftsFolderInContext: context];
|
||||
newDraftMessage = [drafts newDraft];
|
||||
headers = [NSMutableDictionary dictionary];
|
||||
|
||||
|
||||
save = NO;
|
||||
|
||||
value = [[self request] formValueForKey: @"mailto"];
|
||||
@@ -177,4 +189,64 @@
|
||||
return [self _performDelegationAction: @selector (removeDelegates:)];
|
||||
}
|
||||
|
||||
- (WOResponse *) importCertificateAction
|
||||
{
|
||||
NSArray *parts;
|
||||
NGMimeBodyPart *part;
|
||||
NGMimeContentDispositionHeaderField *header;
|
||||
NSData *pkcs12;
|
||||
NSString *mimeType, *name, *password;
|
||||
WOResponse *response;
|
||||
id data;
|
||||
unsigned int count, max;
|
||||
|
||||
password = nil;
|
||||
pkcs12 = nil;
|
||||
response = [self responseWithStatus: 507];
|
||||
|
||||
data = [[[context request] httpRequest] body];
|
||||
|
||||
if (![data isKindOfClass: [NSException class]])
|
||||
{
|
||||
parts = [data parts];
|
||||
max = [parts count];
|
||||
for (count = 0; count < max; count++)
|
||||
{
|
||||
part = [parts objectAtIndex: count];
|
||||
header = (NGMimeContentDispositionHeaderField *)[part headerForKey: @"content-disposition"];
|
||||
name = [header name];
|
||||
if ([name isEqualToString: @"password"])
|
||||
{
|
||||
password = name;
|
||||
}
|
||||
else if ([name isEqualToString: @"file"])
|
||||
{
|
||||
mimeType = [(NGMimeType *)[part headerForKey: @"content-type"] stringValue];
|
||||
if ([mimeType hasSuffix: @"pkcs12"])
|
||||
{
|
||||
pkcs12 = [part body];
|
||||
}
|
||||
else
|
||||
{
|
||||
response = [self responseWithStatus: 507];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (password && pkcs12)
|
||||
{
|
||||
// TODO: append certificate to user defaults
|
||||
response = [self responseWith204];
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
- (WOResponse *) removeCertificateAction
|
||||
{
|
||||
// TODO: remove certificate from user defaults
|
||||
return [self responseWith204];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -433,6 +433,16 @@
|
||||
actionClass = "UIxMailAccountActions";
|
||||
actionName = "removeDelegate";
|
||||
};
|
||||
importCertificate = {
|
||||
protectedBy = "Change Images And Files";
|
||||
actionClass = "UIxMailAccountActions";
|
||||
actionName = "importCertificate";
|
||||
};
|
||||
removeCertificate = {
|
||||
protectedBy = "Change Images And Files";
|
||||
actionClass = "UIxMailAccountActions";
|
||||
actionName = "removeCertificate";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -187,6 +187,8 @@
|
||||
"Collected Address Book" = "Collected Address Book";
|
||||
|
||||
/* IMAP Accounts */
|
||||
"Settings" = "Settings";
|
||||
"Security" = "Security";
|
||||
"Mail Account" = "Mail Account";
|
||||
"New Mail Account" = "New Mail Account";
|
||||
"Server Name" = "Server Name";
|
||||
@@ -204,6 +206,17 @@
|
||||
"Please specify a valid reply-to address." = "Please specify a valid reply-to address.";
|
||||
"Specify a hostname other than the local host" = "Specify a hostname other than the local host";
|
||||
|
||||
"S/MIME Certificate" = "S/MIME Certificate";
|
||||
"No certificate installed" = "No certificate installed";
|
||||
"The SSL certificate must use the PKCS#12 (PFX) format." = "The SSL certificate must use the PKCS#12 (PFX) format.";
|
||||
"Uninstall" = "Uninstall";
|
||||
"Choose PKCS12 Certificate .." = "Choose PKCS12 Certificate ..";
|
||||
"Certificate Password" = "Certificate Password";
|
||||
"Upload" = "Upload";
|
||||
"When composing a message" = "When composing a message";
|
||||
"Digitally sign the message by default" = "Digitally sign the message by default";
|
||||
"Always try to encrypt the message" = "Always try to encrypt the message";
|
||||
|
||||
/* Additional Parameters */
|
||||
"Additional Parameters" = "Additional Parameters";
|
||||
|
||||
|
||||
@@ -20,159 +20,243 @@
|
||||
</md-input-container>
|
||||
</div>
|
||||
</md-toolbar>
|
||||
<md-dialog-content class="md-dialog-content">
|
||||
|
||||
<md-dialog-content>
|
||||
<form id="accountForm" name="accountForm" var:href="ownPath">
|
||||
|
||||
<div layout="row">
|
||||
<md-input-container class="md-block md-flex">
|
||||
<label><var:string label:value="Server Name"/></label>
|
||||
<input name="serverName" type="text" required="required"
|
||||
ng-pattern="$AccountDialogController.hostnameRE"
|
||||
ng-disabled="$AccountDialogController.accountId == 0"
|
||||
ng-model="$AccountDialogController.account.serverName"/>
|
||||
<div ng-messages="accountForm.serverName.$error" role="alert">
|
||||
<div ng-message="pattern"><var:string label:value="Specify a hostname other than the local host"/></div>
|
||||
</div>
|
||||
</md-input-container>
|
||||
<md-tabs class="md-flex" md-border-bottom="md-border-bottom" md-dynamic-height="true">
|
||||
|
||||
<md-input-container class="md-block" flex="30">
|
||||
<label><var:string label:value="Port"/></label>
|
||||
<input type="number" min="1" max="65535"
|
||||
ng-disabled="$AccountDialogController.accountId == 0"
|
||||
ng-model="$AccountDialogController.account.port"
|
||||
placeholder=""
|
||||
sg-placeholder="$AccountDialogController.defaultPort"/>
|
||||
</md-input-container>
|
||||
</div>
|
||||
<!-- general settings -->
|
||||
<md-tab id="accountSettingsView" label:label="Settings">
|
||||
<md-content class="md-padding">
|
||||
|
||||
<md-input-container class="md-block md-input-has-value">
|
||||
<label><var:string label:value="Encryption"/></label>
|
||||
<md-radio-group ng-model="$AccountDialogController.account.encryption">
|
||||
<div layout="row" layout-align="space-around">
|
||||
<div>
|
||||
<md-radio-button
|
||||
ng-click="$AccountDialogController.defaultPort = 143"
|
||||
ng-disabled="$AccountDialogController.accountId == 0"
|
||||
value="none" class="md-primary"><var:string label:value="None"/></md-radio-button>
|
||||
<div layout="row">
|
||||
<md-input-container class="md-block md-flex">
|
||||
<label><var:string label:value="Server Name"/></label>
|
||||
<input name="serverName" type="text" required="required"
|
||||
ng-pattern="$AccountDialogController.hostnameRE"
|
||||
ng-disabled="$AccountDialogController.accountId == 0"
|
||||
ng-model="$AccountDialogController.account.serverName"/>
|
||||
<div ng-messages="accountForm.serverName.$error" role="alert">
|
||||
<div ng-message="pattern"><var:string label:value="Specify a hostname other than the local host"/></div>
|
||||
</div>
|
||||
</md-input-container>
|
||||
|
||||
<md-input-container class="md-block" flex="30">
|
||||
<label><var:string label:value="Port"/></label>
|
||||
<input type="number" min="1" max="65535"
|
||||
ng-disabled="$AccountDialogController.accountId == 0"
|
||||
ng-model="$AccountDialogController.account.port"
|
||||
placeholder=""
|
||||
sg-placeholder="$AccountDialogController.defaultPort"/>
|
||||
</md-input-container>
|
||||
</div>
|
||||
<div>
|
||||
<md-radio-button
|
||||
ng-click="$AccountDialogController.defaultPort = 993"
|
||||
ng-disabled="$AccountDialogController.accountId == 0"
|
||||
value="ssl"><var:string label:value="SSL"/></md-radio-button>
|
||||
|
||||
<md-input-container class="md-block md-input-has-value">
|
||||
<label><var:string label:value="Encryption"/></label>
|
||||
<md-radio-group ng-model="$AccountDialogController.account.encryption">
|
||||
<div layout="row" layout-align="space-around">
|
||||
<div>
|
||||
<md-radio-button
|
||||
ng-click="$AccountDialogController.defaultPort = 143"
|
||||
ng-disabled="$AccountDialogController.accountId == 0"
|
||||
value="none" class="md-primary"><var:string label:value="None"/></md-radio-button>
|
||||
</div>
|
||||
<div>
|
||||
<md-radio-button
|
||||
ng-click="$AccountDialogController.defaultPort = 993"
|
||||
ng-disabled="$AccountDialogController.accountId == 0"
|
||||
value="ssl"><var:string label:value="SSL"/></md-radio-button>
|
||||
</div>
|
||||
<div>
|
||||
<md-radio-button
|
||||
ng-click="$AccountDialogController.defaultPort = 143"
|
||||
ng-disabled="$AccountDialogController.accountId == 0"
|
||||
value="tls"><var:string label:value="TLS"/></md-radio-button>
|
||||
</div>
|
||||
</div>
|
||||
</md-radio-group>
|
||||
</md-input-container>
|
||||
|
||||
<div layout="row">
|
||||
<md-input-container class="md-block" flex="50">
|
||||
<label><var:string label:value="User Name"/></label>
|
||||
<input type="text" required="required"
|
||||
autocomplete="off"
|
||||
ng-disabled="$AccountDialogController.accountId == 0"
|
||||
ng-model="$AccountDialogController.account.userName"/>
|
||||
</md-input-container>
|
||||
|
||||
<md-input-container class="md-block" flex="50"
|
||||
ng-hide="$AccountDialogController.accountId == 0">
|
||||
<label><var:string label:value="Password"/></label>
|
||||
<input type="password"
|
||||
autocomplete="off"
|
||||
ng-model="$AccountDialogController.account.password"/>
|
||||
</md-input-container>
|
||||
</div>
|
||||
<div>
|
||||
<md-radio-button
|
||||
ng-click="$AccountDialogController.defaultPort = 143"
|
||||
ng-disabled="$AccountDialogController.accountId == 0"
|
||||
value="tls"><var:string label:value="TLS"/></md-radio-button>
|
||||
|
||||
<md-input-container class="md-block md-flex">
|
||||
<label><var:string label:value="Full Name"/></label>
|
||||
<input type="text" required="required"
|
||||
ng-disabled="$AccountDialogController.customFromIsReadonly()"
|
||||
ng-model="$AccountDialogController.account.identities[0].fullName"/>
|
||||
</md-input-container>
|
||||
|
||||
<div layout="row">
|
||||
<md-input-container class="md-block" flex="50">
|
||||
<label><var:string label:value="Email"/></label>
|
||||
<input type="email" required="required"
|
||||
ng-disabled="$AccountDialogController.customFromIsReadonly()"
|
||||
ng-model="$AccountDialogController.account.identities[0].email"/>
|
||||
</md-input-container>
|
||||
<md-input-container class="md-block" flex="50"
|
||||
ng-hide="$AccountDialogController.customFromIsReadonly()">
|
||||
<label><var:string label:value="Reply To Email"/></label>
|
||||
<input type="email"
|
||||
autocomplete="off"
|
||||
ng-model="$AccountDialogController.account.identities[0].replyTo"/>
|
||||
</md-input-container>
|
||||
</div>
|
||||
</div>
|
||||
</md-radio-group>
|
||||
</md-input-container>
|
||||
|
||||
<div layout="row">
|
||||
<md-input-container class="md-block" flex="50">
|
||||
<label><var:string label:value="User Name"/></label>
|
||||
<input type="text" required="required"
|
||||
ng-disabled="$AccountDialogController.accountId == 0"
|
||||
ng-model="$AccountDialogController.account.userName"/>
|
||||
</md-input-container>
|
||||
<!-- To switch between a simple text editor and the CK/HTML editor, we use a ng-if and not
|
||||
a ng-class as it doesn't get initialized by the ckEditor class directive -->
|
||||
<md-input-container class="md-block md-flex"
|
||||
ng-if="$AccountDialogController.defaults.SOGoMailComposeMessageType == 'text'">
|
||||
<label><var:string label:value="Signature"/></label>
|
||||
<textarea ng-model="$AccountDialogController.account.identities[0].signature"><!-- signature --></textarea>
|
||||
</md-input-container>
|
||||
<div class="pseudo-input-container"
|
||||
ng-if="$AccountDialogController.defaults.SOGoMailComposeMessageType == 'html'">
|
||||
<label class="pseudo-input-label"><var:string label:value="Signature"/></label>
|
||||
<textarea class="ck-editor"
|
||||
ck-locale="$AccountDialogController.defaults.LocaleCode"
|
||||
ck-options="{ 'autoGrow_minHeight': 70,
|
||||
'toolbar': [['Bold', 'Italic', '-', 'Link',
|
||||
'Font','FontSize','-','TextColor',
|
||||
'BGColor']] }"
|
||||
ck-margin="8px"
|
||||
ng-model="$AccountDialogController.account.identities[0].signature"><!-- signature --></textarea>
|
||||
</div>
|
||||
|
||||
<md-input-container class="md-block" flex="50"
|
||||
ng-hide="$AccountDialogController.accountId == 0">
|
||||
<label><var:string label:value="Password"/></label>
|
||||
<input type="password"
|
||||
ng-model="$AccountDialogController.account.password"/>
|
||||
</md-input-container>
|
||||
</div>
|
||||
<md-input-container class="md-block md-input-has-value">
|
||||
<label><var:string label:value="When I receive a request for a return receipt"/></label>
|
||||
<md-radio-group ng-model="$AccountDialogController.account.receipts.receiptAction">
|
||||
<md-radio-button value="ignore"><var:string label:value="Never send a return receipt"/></md-radio-button>
|
||||
<md-radio-button value="allow"><var:string label:value="Allow return receipts for some messages"/></md-radio-button>
|
||||
</md-radio-group>
|
||||
</md-input-container>
|
||||
|
||||
<md-input-container class="md-block md-flex">
|
||||
<label><var:string label:value="Full Name"/></label>
|
||||
<input type="text" required="required"
|
||||
ng-disabled="$AccountDialogController.customFromIsReadonly()"
|
||||
ng-model="$AccountDialogController.account.identities[0].fullName"/>
|
||||
</md-input-container>
|
||||
<div layout="column" flex-offset="5"
|
||||
ng-show="$AccountDialogController.account.receipts.receiptAction == 'allow'">
|
||||
<md-input-container class="md-block md-flex">
|
||||
<label><var:string label:value="If I'm not in the To or Cc of the message"/></label>
|
||||
<md-select ng-model="$AccountDialogController.account.receipts.receiptNonRecipientAction">
|
||||
<md-option const:value="ignore"><var:string label:value="Never send"/></md-option>
|
||||
<md-option const:value="send"><var:string label:value="Always send"/></md-option>
|
||||
<md-option const:value="ask"><var:string label:value="Ask me"/></md-option>
|
||||
</md-select>
|
||||
</md-input-container>
|
||||
|
||||
<div layout="row">
|
||||
<md-input-container class="md-block" flex="50">
|
||||
<label><var:string label:value="Email"/></label>
|
||||
<input type="email" required="required"
|
||||
ng-disabled="$AccountDialogController.customFromIsReadonly()"
|
||||
ng-model="$AccountDialogController.account.identities[0].email"/>
|
||||
</md-input-container>
|
||||
<md-input-container class="md-block" flex="50"
|
||||
ng-hide="$AccountDialogController.customFromIsReadonly()">
|
||||
<label><var:string label:value="Reply To Email"/></label>
|
||||
<input type="email"
|
||||
ng-model="$AccountDialogController.account.identities[0].replyTo"/>
|
||||
</md-input-container>
|
||||
</div>
|
||||
<md-input-container class="md-block md-flex">
|
||||
<label><var:string label:value="If the sender is outside my domain"/></label>
|
||||
<md-select ng-model="$AccountDialogController.account.receipts.receiptOutsideDomainAction">
|
||||
<md-option const:value="ignore"><var:string label:value="Never send"/></md-option>
|
||||
<md-option const:value="send"><var:string label:value="Always send"/></md-option>
|
||||
<md-option const:value="ask"><var:string label:value="Ask me"/></md-option>
|
||||
</md-select>
|
||||
</md-input-container>
|
||||
|
||||
<!-- To switch between a simple text editor and the CK/HTML editor, we use a ng-if and not
|
||||
a ng-class as it doesn't get initialized by the ckEditor class directive -->
|
||||
<md-input-container class="md-block md-flex"
|
||||
ng-if="$AccountDialogController.defaults.SOGoMailComposeMessageType == 'text'">
|
||||
<label><var:string label:value="Signature"/></label>
|
||||
<textarea ng-model="$AccountDialogController.account.identities[0].signature"><!-- signature --></textarea>
|
||||
</md-input-container>
|
||||
<div class="pseudo-input-container"
|
||||
ng-if="$AccountDialogController.defaults.SOGoMailComposeMessageType == 'html'">
|
||||
<label class="pseudo-input-label"><var:string label:value="Signature"/></label>
|
||||
<textarea class="ck-editor"
|
||||
ck-locale="$AccountDialogController.defaults.LocaleCode"
|
||||
ck-options="{ 'autoGrow_minHeight': 70,
|
||||
'toolbar': [['Bold', 'Italic', '-', 'Link',
|
||||
'Font','FontSize','-','TextColor',
|
||||
'BGColor']] }"
|
||||
ck-margin="8px"
|
||||
ng-model="$AccountDialogController.account.identities[0].signature"><!-- signature --></textarea>
|
||||
</div>
|
||||
<md-input-container class="md-block md-flex">
|
||||
<label><var:string label:value="In all other cases"/></label>
|
||||
<md-select ng-model="$AccountDialogController.account.receipts.receiptAnyAction">
|
||||
<md-option const:value="ignore"><var:string label:value="Never send"/></md-option>
|
||||
<md-option const:value="send"><var:string label:value="Always send"/></md-option>
|
||||
<md-option const:value="ask"><var:string label:value="Ask me"/></md-option>
|
||||
</md-select>
|
||||
</md-input-container>
|
||||
</div>
|
||||
|
||||
<md-input-container class="md-block md-input-has-value">
|
||||
<label><var:string label:value="When I receive a request for a return receipt"/></label>
|
||||
<md-radio-group ng-model="$AccountDialogController.account.receipts.receiptAction">
|
||||
<md-radio-button value="ignore"><var:string label:value="Never send a return receipt"/></md-radio-button>
|
||||
<md-radio-button value="allow"><var:string label:value="Allow return receipts for some messages"/></md-radio-button>
|
||||
</md-radio-group>
|
||||
</md-input-container>
|
||||
</md-content>
|
||||
</md-tab>
|
||||
|
||||
<div layout="column" flex-offset="5"
|
||||
ng-show="$AccountDialogController.account.receipts.receiptAction == 'allow'">
|
||||
<md-input-container class="md-block md-flex">
|
||||
<label><var:string label:value="If I'm not in the To or Cc of the message"/></label>
|
||||
<md-select ng-model="$AccountDialogController.account.receipts.receiptNonRecipientAction">
|
||||
<md-option const:value="ignore"><var:string label:value="Never send"/></md-option>
|
||||
<md-option const:value="send"><var:string label:value="Always send"/></md-option>
|
||||
<md-option const:value="ask"><var:string label:value="Ask me"/></md-option>
|
||||
</md-select>
|
||||
</md-input-container>
|
||||
<!-- security tab -->
|
||||
<md-tab id="accountSecurityView" label:label="Security">
|
||||
<md-content id="accountSecurityContent" class="md-padding" layout="column">
|
||||
|
||||
<md-input-container class="md-block md-flex">
|
||||
<label><var:string label:value="If the sender is outside my domain"/></label>
|
||||
<md-select ng-model="$AccountDialogController.account.receipts.receiptOutsideDomainAction">
|
||||
<md-option const:value="ignore"><var:string label:value="Never send"/></md-option>
|
||||
<md-option const:value="send"><var:string label:value="Always send"/></md-option>
|
||||
<md-option const:value="ask"><var:string label:value="Ask me"/></md-option>
|
||||
</md-select>
|
||||
</md-input-container>
|
||||
<div layout="row" layout-align="start center">
|
||||
<md-input-container
|
||||
class="md-flex"
|
||||
ng-class="{'md-input-invalid': $AccountDialogController.form.certificateFilename.$error.fileformat}">
|
||||
<label><var:string label:value="S/MIME Certificate"/></label>
|
||||
<input type="text" name="certificateFilename"
|
||||
ng-disabled="true"
|
||||
label:placeholder="No certificate installed"
|
||||
ng-model="$AccountDialogController.certificateFilename" />
|
||||
<div ng-messages="accountForm.certificateFilename.$error" role="alert">
|
||||
<div ng-message="fileformat"><var:string label:value="The SSL certificate must use the PKCS#12 (PFX) format."/></div>
|
||||
</div>
|
||||
</md-input-container>
|
||||
<md-button ng-show="$AccountDialogController.certificateIsInstalled()"
|
||||
ng-click="$AccountDialogController.removeCertificate()">
|
||||
<var:string label:value="Uninstall"/>
|
||||
</md-button>
|
||||
<div ng-hide="$AccountDialogController.certificateIsInstalled()">
|
||||
<input id="smime-certificate-import" type="file" class="ng-hide"
|
||||
nv-file-select="nv-file-select"
|
||||
uploader="$AccountDialogController.uploader"/>
|
||||
<label class="md-button" for="smime-certificate-import"
|
||||
ng-click="$AccountDialogController.onBeforeUploadCertificate(accountForm)"
|
||||
ng-hide="$AccountDialogController.uploader.isUploading">
|
||||
<span><var:string label:value="Choose PKCS12 Certificate .."/></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<md-input-container class="md-flex">
|
||||
<label><var:string label:value="Certificate Password"/></label>
|
||||
<input type="password" autocomplete="new-password"
|
||||
ng-required="$AccountDialogController.uploader.queue.length"
|
||||
ng-model="$AccountDialogController.certificatePassword" />
|
||||
</md-input-container>
|
||||
|
||||
<md-input-container class="md-block md-flex">
|
||||
<label><var:string label:value="In all other cases"/></label>
|
||||
<md-select ng-model="$AccountDialogController.account.receipts.receiptAnyAction">
|
||||
<md-option const:value="ignore"><var:string label:value="Never send"/></md-option>
|
||||
<md-option const:value="send"><var:string label:value="Always send"/></md-option>
|
||||
<md-option const:value="ask"><var:string label:value="Ask me"/></md-option>
|
||||
</md-select>
|
||||
</md-input-container>
|
||||
</div>
|
||||
<div layout="row" layout-align="end end">
|
||||
<md-button
|
||||
class="md-warn md-raised"
|
||||
ng-disabled="!$AccountDialogController.certificatePassword || !$AccountDialogController.certificateFilename"
|
||||
ng-click="$AccountDialogController.importCertificate()">
|
||||
<var:string label:value="Upload"/>
|
||||
</md-button>
|
||||
</div>
|
||||
|
||||
<md-divider><!-- divider --></md-divider>
|
||||
|
||||
<div class="pseudo-input-container">
|
||||
<label class="pseudo-input-label"><var:string label:value="When composing a message"/></label>
|
||||
<div layout="column">
|
||||
<md-checkbox
|
||||
class="pseudo-input-field"
|
||||
ng-model="$AccountDialogController.account.alwaysSign"
|
||||
ng-disabled="!$AccountDialogController.certificateIsInstalled()"
|
||||
ng-true-value="1"
|
||||
ng-false-value="0"><var:string label:value="Digitally sign the message by default"/></md-checkbox>
|
||||
<md-checkbox
|
||||
class="pseudo-input-field"
|
||||
ng-model="$AccountDialogController.account.alwaysEncrypt"
|
||||
ng-disabled="!$AccountDialogController.certificateIsInstalled()"
|
||||
ng-true-value="1"
|
||||
ng-false-value="0"><var:string label:value="Always try to encrypt the message"/></md-checkbox>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</md-content>
|
||||
</md-tab>
|
||||
|
||||
</md-tabs>
|
||||
|
||||
</form>
|
||||
</md-dialog-content>
|
||||
<md-dialog-actions>
|
||||
<md-button type="button" ng-click="$AccountDialogController.cancel()"><var:string label:value="Cancel"/></md-button>
|
||||
<md-button aria-label="{{::'OK' | loc}}"
|
||||
<md-button class="md-primary" aria-label="{{::'OK' | loc}}"
|
||||
ng-disabled="accountForm.$invalid"
|
||||
ng-click="$AccountDialogController.save()"
|
||||
ng-bind="::'OK' | loc"><!-- OK --></md-button>
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
xmlns:label="OGo:label"
|
||||
className="UIxPageFrame"
|
||||
title="title"
|
||||
const:jsFiles="vendor/ckeditor/ckeditor.js, vendor/ckeditor/ck.js, vendor/ng-sortable.min.js, Common.js, Preferences.js, Preferences.services.js, Mailer.services.js, Contacts.services.js">
|
||||
const:jsFiles="vendor/ckeditor/ckeditor.js, vendor/ckeditor/ck.js, vendor/angular-file-upload.min.js, vendor/ng-sortable.min.js, Common.js, Preferences.js, Preferences.services.js, Mailer.services.js, Contacts.services.js">
|
||||
|
||||
<main layout-fill="layout-fill" ui-view="preferences"
|
||||
ng-controller="navController"><!-- preferences --> </main>
|
||||
|
||||
@@ -20,7 +20,8 @@
|
||||
var alert = this.$modal.alert()
|
||||
.title(title)
|
||||
.htmlContent(content)
|
||||
.ok(l('OK'));
|
||||
.ok(l('OK'))
|
||||
.multiple(true);
|
||||
this.$modal.show(alert);
|
||||
};
|
||||
|
||||
|
||||
@@ -287,6 +287,18 @@
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @function $removeCertificate
|
||||
* @memberof Account.prototype
|
||||
* @desc Remove any S/MIME certificate associated with the account.
|
||||
* @returns a promise of the HTTP operation
|
||||
*/
|
||||
Account.prototype.$removeCertificate = function() {
|
||||
var _this = this;
|
||||
|
||||
return Account.$$resource.fetch(this.id.toString(), 'removeCertificate');
|
||||
};
|
||||
|
||||
/**
|
||||
* @function updateQuota
|
||||
* @memberof Account.prototype
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
/**
|
||||
* @ngInject
|
||||
*/
|
||||
AccountDialogController.$inject = ['$mdDialog', 'defaults', 'account', 'accountId', 'mailCustomFromEnabled'];
|
||||
function AccountDialogController($mdDialog, defaults, account, accountId, mailCustomFromEnabled) {
|
||||
AccountDialogController.$inject = ['$mdDialog', '$mdToast', 'FileUploader', 'Dialog', 'sgSettings', 'Account', 'defaults', 'account', 'accountId', 'mailCustomFromEnabled'];
|
||||
function AccountDialogController($mdDialog, $mdToast, FileUploader, Dialog, Settings, Account, defaults, account, accountId, mailCustomFromEnabled) {
|
||||
var vm = this;
|
||||
|
||||
vm.defaultPort = 143;
|
||||
@@ -16,6 +16,10 @@
|
||||
vm.account = account;
|
||||
vm.accountId = accountId;
|
||||
vm.customFromIsReadonly = customFromIsReadonly;
|
||||
vm.onBeforeUploadCertificate = onBeforeUploadCertificate;
|
||||
vm.certificateIsInstalled = certificateIsInstalled;
|
||||
vm.removeCertificate = removeCertificate;
|
||||
vm.importCertificate = importCertificate;
|
||||
vm.cancel = cancel;
|
||||
vm.save = save;
|
||||
vm.hostnameRE = accountId > 0 ? /^(?!(127\.0\.0\.1|localhost(?:\.localdomain)?)$)/ : /./;
|
||||
@@ -25,13 +29,65 @@
|
||||
else if (vm.account.encryption == "ssl")
|
||||
vm.defaultPort = 993;
|
||||
|
||||
if (vm.account.certificateFilename)
|
||||
vm.certificateFilename = vm.account.certificateFilename;
|
||||
|
||||
vm.uploader = new FileUploader({
|
||||
url: [Settings.activeUser('folderURL') + 'Mail', accountId, 'importCertificate'].join('/'),
|
||||
autoUpload: false,
|
||||
queueLimit: 1,
|
||||
filters: [{ name: filterByExtension, fn: filterByExtension }],
|
||||
onAfterAddingFile: function(item) {
|
||||
vm.certificateFilename = item.file.name;
|
||||
},
|
||||
onSuccessItem: function(item, response, status, headers) {
|
||||
var el = angular.element(document.getElementById('accountSecurityContent'));
|
||||
$mdToast.show(
|
||||
$mdToast.simple()
|
||||
.content(l('Success'))
|
||||
.parent(el)
|
||||
.position('top right')
|
||||
.hideDelay(3000));
|
||||
this.clearQueue();
|
||||
},
|
||||
onErrorItem: function(item, response, status, headers) {
|
||||
Dialog.alert(l('Error'), l('An error occurred while importing the certificate. Verify your password.'));
|
||||
}
|
||||
});
|
||||
|
||||
function filterByExtension(item) {
|
||||
var isP12File = item.type.indexOf('pkcs12') > 0 || /\.(p12|pfx)$/.test(item.name);
|
||||
vm.form.certificateFilename.$setValidity('fileformat', isP12File);
|
||||
return isP12File;
|
||||
}
|
||||
|
||||
function customFromIsReadonly() {
|
||||
if (accountId > 0)
|
||||
return false;
|
||||
|
||||
return !mailCustomFromEnabled;
|
||||
}
|
||||
|
||||
function importCertificate() {
|
||||
vm.uploader.queue[0].formData = [{ password: vm.certificatePassword }];
|
||||
vm.uploader.uploadAll();
|
||||
}
|
||||
|
||||
function onBeforeUploadCertificate(form) {
|
||||
vm.form = form;
|
||||
vm.uploader.clearQueue();
|
||||
}
|
||||
|
||||
function certificateIsInstalled() {
|
||||
return vm.certificateFilename && vm.uploader.queue.length === 0;
|
||||
}
|
||||
|
||||
function removeCertificate() {
|
||||
var accountObject = new Account({ id: accountId });
|
||||
accountObject.$removeCertificate().then(function() {
|
||||
delete vm.certificateFilename;
|
||||
});
|
||||
}
|
||||
|
||||
function cancel() {
|
||||
$mdDialog.cancel();
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
angular.module('SOGo.PreferencesUI', ['ui.router', 'ck', 'SOGo.Common', 'SOGo.MailerUI', 'SOGo.ContactsUI', 'SOGo.Authentication', 'as.sortable'])
|
||||
angular.module('SOGo.PreferencesUI', ['ui.router', 'ck', 'angularFileUpload', 'SOGo.Common', 'SOGo.MailerUI', 'SOGo.ContactsUI', 'SOGo.Authentication', 'as.sortable'])
|
||||
.config(configure)
|
||||
.run(runBlock);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user