166 lines
8.0 KiB
HTML
166 lines
8.0 KiB
HTML
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<meta charset="utf-8" />
|
|
<meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height" />
|
|
|
|
<!-- this gets changed once we get the status (because angular has not loaded yet, we see template string for a flash) -->
|
|
<title>Cloudron Password Reset</title>
|
|
<meta name="description" content="Cloudron Password Reset">
|
|
|
|
<link id="favicon" href="/api/v1/cloudron/avatar" rel="icon" type="image/png">
|
|
|
|
<!-- contains all thing already using import statement -->
|
|
<script type="module" src="./src/modules.js"></script>
|
|
|
|
<!-- Theme CSS -->
|
|
<link type="text/css" rel="stylesheet" href="./src/theme.scss">
|
|
|
|
<!-- jQuery-->
|
|
<script type="text/javascript" src="/js/jquery.min.js"></script>
|
|
|
|
<!-- async -->
|
|
<script type="text/javascript" src="/js/async-3.2.0.min.js"></script>
|
|
|
|
<!-- Showdown (markdown converter) -->
|
|
<script type="text/javascript" src="/js/showdown-1.9.1.min.js"></script>
|
|
|
|
<!-- Angularjs scripts -->
|
|
<script type="text/javascript" src="/js/angular.min.js"></script>
|
|
<script type="text/javascript" src="/js/angular-loader.min.js"></script>
|
|
<script type="text/javascript" src="/js/angular-cookies.min.js"></script>
|
|
|
|
<!-- Angular directives for bootstrap https://angular-ui.github.io/bootstrap/ -->
|
|
<script type="text/javascript" src="/js/ui-bootstrap-tpls-1.3.3.min.js"></script>
|
|
|
|
<!-- Angular translate https://angular-translate.github.io/ -->
|
|
<script type="text/javascript" src="/js/angular-translate.min.js"></script>
|
|
<script type="text/javascript" src="/js/angular-translate-loader-static-files.min.js"></script>
|
|
<script type="text/javascript" src="/js/angular-translate-storage-cookie.min.js"></script>
|
|
<script type="text/javascript" src="/js/angular-translate-storage-local.min.js"></script>
|
|
|
|
<!-- Setup Application -->
|
|
<script type="text/javascript" src="/js/passwordreset.js?%VITE_CACHE_ID%"></script>
|
|
<script type="text/javascript" src="/js/utils.js?%VITE_CACHE_ID%"></script>
|
|
|
|
</head>
|
|
|
|
<body ng-app="Application" ng-controller="PasswordResetController">
|
|
|
|
<div class="layout-root ng-cloak" ng-show="initialized">
|
|
|
|
<div class="layout-content" ng-show="mode === 'passwordReset'">
|
|
<div class="card" style="padding: 20px; margin-top: 100px; max-width: 620px;">
|
|
<div class="row">
|
|
<div class="col-md-12" style="text-align: center;">
|
|
<img width="128" height="128" style="margin-top: -84px" src="/api/v1/cloudron/avatar"/>
|
|
<br/>
|
|
<h2>{{ 'passwordReset.title' | tr }}</h2>
|
|
</div>
|
|
</div>
|
|
<br/>
|
|
<div class="row">
|
|
<div class="col-md-12">
|
|
<form name="passwordResetForm" ng-submit="onPasswordReset()">
|
|
<div class="form-group">
|
|
<label class="control-label" for="inputPasswordResetIdentifier">{{ 'passwordReset.usernameOrEmail' | tr }}</label>
|
|
<input type="text" class="form-control" id="inputPasswordResetIdentifier" name="passwordResetIdentifier" ng-model="passwordResetIdentifier" ng-disabled="busy" autofocus required>
|
|
</div>
|
|
<br/>
|
|
<div class="card-form-bottom-bar">
|
|
<a href="/" class="hand">{{ 'passwordReset.backToLoginAction' | tr }}</a>
|
|
<button class="btn btn-primary btn-outline" type="submit" ng-disabled="busy || passwordResetForm.$invalid"><i class="fa fa-circle-notch fa-spin" ng-show="busy"></i> {{ 'passwordReset.resetAction' | tr }}</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="layout-content" ng-show="mode === 'passwordResetDone'">
|
|
<div class="card" style="padding: 20px; margin-top: 100px; max-width: 620px;">
|
|
<div class="row">
|
|
<div class="col-md-12" style="text-align: center;">
|
|
<img width="128" height="128" style="margin-top: -84px" src="/api/v1/cloudron/avatar"/>
|
|
<br/>
|
|
<h2 ng-hide="error">{{ 'passwordReset.emailSent.title' | tr }}</h2>
|
|
<h4 ng-show="error" class="has-error">{{ error }}</h4>
|
|
<br/>
|
|
<a href="/" class="btn btn-primary">{{ 'passwordReset.backToLoginAction' | tr }}</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="layout-content" ng-show="mode === 'newPassword'">
|
|
<div class="card" style="padding: 20px; margin-top: 100px; max-width: 620px;">
|
|
<div class="row">
|
|
<div class="col-md-12" style="text-align: center;">
|
|
<img width="128" height="128" style="margin-top: -84px" src="/api/v1/cloudron/avatar"/>
|
|
<br/>
|
|
<h2>{{ 'passwordReset.newPassword.title' | tr }}</h2>
|
|
</div>
|
|
</div>
|
|
<br/>
|
|
<div class="row">
|
|
<div class="col-md-12">
|
|
<h4 class="has-error" ng-show="error">{{ error }}</h4>
|
|
</div>
|
|
</div>
|
|
<br/>
|
|
<div class="row">
|
|
<div class="col-md-12">
|
|
<form name="newPasswordForm" ng-submit="onNewPassword()">
|
|
<input type="password" style="display: none;"/>
|
|
<div class="form-group" ng-class="{ 'has-error': newPasswordForm.newPassword.$dirty && newPasswordForm.newPassword.$invalid }">
|
|
<label class="control-label" for="inputNewPassword">{{ 'passwordReset.newPassword.password' | tr }}</label>
|
|
<div class="control-label" ng-show="newPasswordForm.newPassword.$dirty && newPasswordForm.newPassword.$invalid">
|
|
<small ng-show="newPasswordForm.newPassword.$dirty && newPasswordForm.newPassword.$invalid">{{ 'passwordReset.newPassword.errorLength' | tr }}</small>
|
|
</div>
|
|
<input type="password" class="form-control" id="inputNewPassword" ng-model="newPassword" name="newPassword" ng-minlength="8" ng-maxlength="256" autofocus required password-reveal>
|
|
</div>
|
|
<div class="form-group" ng-class="{ 'has-error': newPasswordForm.newPasswordRepeat.$dirty && (newPassword !== newPasswordRepeat) }">
|
|
<label class="control-label" for="inputNewPasswordRepeat">{{ 'passwordReset.newPassword.passwordRepeat' | tr }}</label>
|
|
<div class="control-label" ng-show="newPasswordForm.newPasswordRepeat.$dirty && (newPassword !== newPasswordRepeat)">
|
|
<small ng-show="newPasswordForm.newPasswordRepeat.$dirty && (newPassword !== newPasswordRepeat)">{{ 'passwordReset.newPassword.errorMismatch' | tr }}</small>
|
|
</div>
|
|
<input type="password" class="form-control" id="inputNewPasswordRepeat" ng-model="newPasswordRepeat" name="newPasswordRepeat" required password-reveal>
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="control-label" for="inputPasswordResetTotpToken">{{ 'login.2faToken' | tr }}</label>
|
|
<input type="text" class="form-control" name="passwordResetTotpToken" id="inputPasswordResetTotpToken" ng-model="totpToken" ng-disabled="busy" value="">
|
|
</div>
|
|
<div class="card-form-bottom-bar">
|
|
<a href="/" class="hand">{{ 'passwordReset.backToLoginAction' | tr }}</a>
|
|
<button class="btn btn-primary btn-outline" type="submit" ng-disabled="busy || newPasswordForm.$invalid || newPassword !== newPasswordRepeat"><i class="fa fa-circle-notch fa-spin" ng-show="busy"></i> {{ 'passwordReset.passwordChanged.submitAction' | tr }}</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="layout-content" ng-show="mode === 'newPasswordDone'">
|
|
<div class="card" style="padding: 20px; margin-top: 100px; max-width: 620px;">
|
|
<div class="row">
|
|
<div class="col-md-12" style="text-align: center;">
|
|
<img width="128" height="128" style="margin-top: -84px" src="/api/v1/cloudron/avatar"/>
|
|
<br/>
|
|
<h2>{{ 'passwordReset.success.title' | tr }}</h2>
|
|
<br/>
|
|
<a href="/" class="btn btn-primary">{{ 'passwordReset.success.openDashboardAction' | tr }}</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<footer class="text-center">
|
|
<span class="text-muted" ng-bind-html="branding.footer | markdown2html"></span>
|
|
</footer>
|
|
|
|
</div>
|
|
|
|
</body>
|
|
</html>
|
|
|