268 lines
13 KiB
XML
268 lines
13 KiB
XML
<?xml version="1.0" standalone="yes"?>
|
|
<!DOCTYPE var:component>
|
|
<var:component
|
|
className="UIxPageFrame"
|
|
xmlns="http://www.w3.org/1999/xhtml"
|
|
xmlns:var="http://www.skyrix.com/od/binding"
|
|
xmlns:const="http://www.skyrix.com/od/constant"
|
|
xmlns:rsrc="OGo:url"
|
|
xmlns:label="OGo:label"
|
|
const:jsFiles="Main.js, Common.js"
|
|
>
|
|
<script type="text/javascript">
|
|
var cookieUsername = <var:string var:value="cookieUsername.doubleQuotedString" const:escapeHTML="NO"/>;
|
|
var language = '<var:string var:value="language" const:escapeHTML="NO"/>';
|
|
</script>
|
|
|
|
<!--
|
|
MAIN CONTENT ROW
|
|
Content of the application view injected injected in the element bellow
|
|
MUST be the first html element after body
|
|
SHOULD be a main tag (with role="main")
|
|
-->
|
|
<main class="view md-default-theme md-background md-hue-1 md-bg"
|
|
layout-gt-md="row" layout-align-gt-md="center start" layout-fill="layout-fill"
|
|
ui-view="login"
|
|
ng-controller="LoginController as app">
|
|
<md-content id="loginContent" class="ng-cloak md-whiteframe-3dp" flex="100"
|
|
layout="column" layout-gt-md="row" layout-align="start stretch"
|
|
ng-show="app.showLogin">
|
|
<div class="sg-logo" flex-gt-md="50">
|
|
<div layout="row" class="md-padding">
|
|
<div class="md-flex hide show-gt-md"><!-- push logo to the right on larger screens --></div>
|
|
<img const:alt="*" class="md-margin" rsrc:src="img/sogo-full.svg"/>
|
|
</div>
|
|
</div>
|
|
<div class="sg-login md-default-theme md-bg md-accent" flex-gt-md="50">
|
|
<div id="login" class="sg-login-content md-padding">
|
|
<form name="loginForm" layout="column"
|
|
ng-cloak="ng-cloak"
|
|
ng-submit="app.login()">
|
|
<var:if condition="hasLoginSuffix">
|
|
<input type="hidden" ng-model="app.creds.loginSuffix" var:value="loginSuffix"/>
|
|
</var:if>
|
|
<md-input-container class="md-block">
|
|
<label><var:string label:value="Username"/></label>
|
|
<md-icon>person</md-icon>
|
|
<input autocorrect="off" autocapitalize="off" type="text" ng-model="app.creds.username" ng-required="true"/>
|
|
</md-input-container>
|
|
<md-input-container class="md-block">
|
|
<label><var:string label:value="Password"/></label>
|
|
<md-icon>email</md-icon>
|
|
<input type="password" ng-model="app.creds.password" ng-required="true"/>
|
|
</md-input-container>
|
|
|
|
<!-- LANGUAGES SELECT -->
|
|
<div layout="row" layout-align="start end">
|
|
<md-icon>language</md-icon>
|
|
<md-input-container class="md-flex">
|
|
<label><var:string label:value="choose"/></label>
|
|
<md-select ng-model="app.creds.language"
|
|
var:placeholder="localizedLanguage"
|
|
ng-change="app.changeLanguage($event)">
|
|
<var:foreach list="languages" item="item">
|
|
<md-option var:value="item">
|
|
<var:string value="languageText"/>
|
|
</md-option>
|
|
</var:foreach>
|
|
</md-select>
|
|
</md-input-container>
|
|
</div>
|
|
|
|
<!-- DOMAINS SELECT -->
|
|
<var:if condition="hasLoginDomains">
|
|
<div layout="row" layout-align="start end">
|
|
<md-icon>domain</md-icon>
|
|
<md-input-container class="md-flex">
|
|
<md-select class="md-flex" ng-model="app.creds.domain" label:placeholder="choose">
|
|
<var:foreach list="loginDomains" item="item">
|
|
<md-option var:value="item">
|
|
<var:string value="item"/>
|
|
</md-option>
|
|
</var:foreach>
|
|
</md-select>
|
|
</md-input-container>
|
|
</div>
|
|
</var:if>
|
|
|
|
<div layout="row" layout-align="center center">
|
|
<md-switch class="md-accent md-hue-2"
|
|
ng-model="app.creds.rememberLogin"
|
|
label:arial-label="Remember username">
|
|
<var:string label:value="Remember username"/>
|
|
</md-switch>
|
|
</div>
|
|
|
|
<!-- CONNECT BUTTON -->
|
|
<div layout="row" layout-align="space-between center">
|
|
<md-button class="md-icon-button"
|
|
label:aria-label="About"
|
|
ng-click="app.showAbout()">
|
|
<md-icon>info</md-icon>
|
|
</md-button>
|
|
<md-button class="md-fab md-accent md-hue-2" type="submit"
|
|
label:aria-label="Connect"
|
|
ng-if="!app.loginState"
|
|
ng-disabled="loginForm.$invalid"
|
|
sg-ripple-click="loginContent">
|
|
<md-icon>arrow_forward</md-icon>
|
|
</md-button>
|
|
</div>
|
|
|
|
<sg-ripple class="md-default-theme md-accent md-bg"
|
|
ng-class="{ 'md-warn': app.loginState == 'error' }"><!-- ripple background --></sg-ripple>
|
|
<sg-ripple-content class="md-flex ng-hide"
|
|
layout="column" layout-align="center center" layout-fill="layout-fill"
|
|
ng-switch="app.loginState">
|
|
|
|
<!-- Authenticating -->
|
|
<div layout="column" layout-align="center center"
|
|
ng-switch-when="authenticating">
|
|
<md-progress-circular class="md-hue-1"
|
|
md-mode="indeterminate"
|
|
md-diameter="32"><!-- mailbox loading progress --></md-progress-circular>
|
|
<div class="md-default-theme md-accent md-hue-1 md-fg md-padding">
|
|
<var:string label:value="Authenticating"/>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Google Authenticator Code -->
|
|
<var:if condition="isGoogleAuthenticatorEnabled">
|
|
<div layout="row" layout-align="center center" layout-fill="layout-fill"
|
|
ng-switch-when="googleauthenticatorcode">
|
|
<div flex="80" flex-sm="50" flex-gt-sm="40">
|
|
<md-input-container class="md-block">
|
|
<label><var:string label:value="Verification Code"/></label>
|
|
<md-icon>lock</md-icon>
|
|
<input type="text" ng-pattern="app.verificationCodePattern" ng-model="app.creds.verificationCode" ng-required="app.loginState == 'googleauthenticatorcode'"/>
|
|
<div class="sg-hint"><var:string label:value="Enter the 6-digit verification code from your Google Authenticator application."/></div>
|
|
</md-input-container>
|
|
<div layout="row" layout-align="space-between center">
|
|
<md-button class="md-icon-button"
|
|
label:aria-label="Cancel"
|
|
ng-click="app.restoreLogin()"
|
|
sg-ripple-click="loginContent">
|
|
<md-icon>arrow_backward</md-icon>
|
|
</md-button>
|
|
<md-button class="md-fab md-accent md-hue-2" type="submit"
|
|
label:aria-label="Connect"
|
|
ng-if="app.loginState == 'googleauthenticatorcode'"
|
|
ng-disabled="loginForm.$invalid"
|
|
ng-click="app.login()">
|
|
<md-icon>arrow_forward</md-icon>
|
|
</md-button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</var:if>
|
|
|
|
<!-- Password policy: Password is expired -->
|
|
<div layout="column" layout-align="center center"
|
|
ng-switch-when="passwordexpired">
|
|
<md-icon class="md-accent md-hue-1 sg-icon--large">watch_later</md-icon>
|
|
<div class="md-default-theme md-accent md-hue-1 md-fg md-padding">
|
|
<var:string label:value="Your password has expired, please enter a new one below"/>
|
|
</div>
|
|
<div flex="100">
|
|
<div layout="row" layout-xs="column">
|
|
<md-input-container class="md-block" flex="flex">
|
|
<label><var:string label:value="Current password"/>
|
|
</label>
|
|
<input type="password" sg-no-dirty-check="true" ng-model="app.passwords.oldPassword"/>
|
|
</md-input-container>
|
|
<md-input-container class="md-block" flex="flex">
|
|
<label><var:string label:value="New password"/>
|
|
</label>
|
|
<input type="password" sg-no-dirty-check="true" ng-model="app.passwords.newPassword"/>
|
|
</md-input-container>
|
|
<md-input-container class="md-block" flex="flex">
|
|
<label><var:string label:value="Confirmation"/>
|
|
</label>
|
|
<input type="password" name="newPasswordConfirmation" sg-no-dirty-check="true" ng-model="app.passwords.newPasswordConfirmation"/>
|
|
<div ng-messages="loginForm.newPasswordConfirmation.$error">
|
|
<div ng-message="newPasswordMismatch"><var:string label:value="Passwords don't match"/></div>
|
|
</div>
|
|
</md-input-container>
|
|
</div>
|
|
<div layout="row" layout-align="end center">
|
|
<md-button ng-click="app.changePassword()" type="button" ng-disabled="!app.canChangePassword(loginForm)">
|
|
<var:string label:value="Change"/>
|
|
</md-button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Password policy: Grace period -->
|
|
<div layout="column" layout-align="center center"
|
|
ng-switch-when="passwordwillexpire">
|
|
<md-icon class="md-accent md-hue-1 sg-icon--large">warning</md-icon>
|
|
<div class="md-default-theme md-accent md-hue-1 md-fg md-padding" ng-if="app.cn">
|
|
<var:string label:value="Welcome"/> {{app.cn}}
|
|
</div>
|
|
<div class="md-default-theme md-warn md-hue-1 md-bg md-padding">
|
|
{{app.errorMessage}}
|
|
<md-button class="md-raised"
|
|
ng-click="app.loginState = 'passwordexpired'"><var:string label:value="Change your Password"/></md-button>
|
|
</div>
|
|
<md-button
|
|
ng-click="app.continueLogin()"
|
|
sg-ripple-click="loginContent"><var:string label:value="Continue"/></md-button>
|
|
</div>
|
|
|
|
<!-- Logged in -->
|
|
<div layout="column" layout-align="center center"
|
|
ng-switch-when="logged">
|
|
<md-icon class="md-accent md-hue-1 sg-icon--large">done</md-icon>
|
|
<div class="md-default-theme md-accent md-hue-1 md-fg md-padding">
|
|
<var:string label:value="Welcome"/> {{app.cn}}
|
|
</div>
|
|
</div>
|
|
|
|
<div layout="column" layout-align="center center"
|
|
ng-switch-when="message">
|
|
<md-icon class="md-accent md-hue-1 sg-icon--large">done</md-icon>
|
|
<div class="md-default-theme md-accent md-hue-1 md-fg md-padding">
|
|
{{app.errorMessage}}
|
|
</div>
|
|
<md-button
|
|
ng-click="app.continueLogin()"
|
|
sg-ripple-click="loginContent"><var:string label:value="Continue"/></md-button>
|
|
</div>
|
|
|
|
<!-- Error -->
|
|
<div layout="column" layout-align="center center"
|
|
ng-switch-when="error">
|
|
<md-icon class="md-accent md-hue-1 sg-icon--large">error</md-icon>
|
|
<div class="md-default-theme md-accent md-hue-1 md-fg md-padding">
|
|
{{app.errorMessage}}
|
|
</div>
|
|
<md-button
|
|
ng-click="app.restoreLogin()"
|
|
sg-ripple-click="loginContent"><var:string label:value="Retry"/></md-button>
|
|
</div>
|
|
|
|
</sg-ripple-content>
|
|
</form>
|
|
|
|
</div>
|
|
</div>
|
|
</md-content>
|
|
</main>
|
|
|
|
<script type="text/ng-template" id="aboutBox.html">
|
|
<md-dialog flex="50" flex-xs="100">
|
|
<md-dialog-content class="md-dialog-content">
|
|
<p><a href="http://sogo.nu/" target="_new">sogo.nu</a></p>
|
|
<p>Version <var:string value="version"/> (<var:string value="buildDate" />)</p>
|
|
<br/>
|
|
<p><var:string label:value="AboutBox" const:escapeHTML="NO"/></p>
|
|
<!--<img class="full-image" const:alt="Inverse" rsrc:src="img/inverse.png"/>-->
|
|
</md-dialog-content>
|
|
<md-dialog-actions>
|
|
<md-button ng-click="about.closeDialog()"><var:string label:value="Close"/></md-button>
|
|
</md-dialog-actions>
|
|
</md-dialog>
|
|
</script>
|
|
|
|
</var:component>
|