Files
raven-client/ayanova/src/views/login.vue
2021-02-10 15:53:45 +00:00

495 lines
15 KiB
Vue

<template>
<div>
<v-row align="center" justify="center" class="mx-auto mt-sm-12 mb-16">
<v-col cols="12" offset-md="4">
<form>
<v-row>
<!-- Customer logo -->
<v-col v-if="showCustomSmallLogo()" cols="12">
<div class="text-center">
<img :src="mediumLogoUrl" />
</div>
</v-col>
<v-col v-if="showCustomMediumLogo()" cols="7">
<div class="text-center">
<img :src="mediumLogoUrl" />
</div>
</v-col>
<v-col v-if="showCustomLargeLogo()" cols="7">
<div class="text-center">
<img :src="largeLogoUrl" />
</div>
</v-col>
<!-- Small AyaNova logo -->
<v-col cols="12" v-if="showSmallBrandLogo()">
<v-img
:src="require('../assets/logo.svg')"
contain
height="64"
></v-img>
</v-col>
<!-- Large AyaNova logo. -->
<v-col cols="7" class="ml-16" v-if="showLargeBrandLogo()">
<v-img
:src="require('../assets/logo.svg')"
contain
height="128"
></v-img>
</v-col>
<v-col cols="12" md="7" v-if="formState.errorBoxMessage">
<gz-error
:error-box-message="formState.errorBoxMessage"
></gz-error>
</v-col>
<v-col cols="12" md="7" v-if="showEvalUsers == true">
<v-select
v-model="selectedTrialUserId"
:items="selectLists.trialUsers"
item-text="name"
item-value="l"
label="Trial mode example users"
prepend-icon="$ayiQuestionCircle"
@click:prepend="trialHelpClick"
@input="trialUserSelected"
return-object
data-cy="selecttrialuser"
>
</v-select>
</v-col>
<v-col cols="12" md="7">
<v-text-field
name="username"
id="username"
v-model="input.username"
prepend-icon="$ayiUser"
autofocus
autocomplete="off"
autocorrect="off"
autocapitalize="off"
spellcheck="false"
:error="errorBadCreds"
v-focus
@keyup.enter="onEnterUserName"
></v-text-field>
</v-col>
<v-col cols="12" md="7">
<v-text-field
name="password"
id="password"
v-model="input.password"
:append-outer-icon="reveal ? '$ayiEye' : '$ayiEyeSlash'"
prepend-icon="$ayiKey"
:type="reveal ? 'text' : 'password'"
:error="errorBadCreds"
@keyup.enter="login"
@click:append-outer="reveal = !reveal"
></v-text-field>
</v-col>
<v-col cols="12" md="7" mt-1 mb-5>
<v-btn color="primary" @click="login()" value="LOGIN">
<v-icon>$ayiSignIn</v-icon>
</v-btn>
</v-col>
<template v-if="$ay.dev">
<v-col cols="12">
<span class="subtitle-2 secondary--text">DEVELOPMENT MODE</span>
</v-col>
</template>
</v-row>
</form>
</v-col>
</v-row>
<v-footer color="primary" padless absolute>
<div
v-if="showFooterLogo()"
style="text-align: center;"
class="mx-auto pa-4 mb-10 mb-sm-1 mt-n8"
>
<a
href="https://ayanova.com"
target="_blank"
style="text-decoration:none"
class="primary white--text text-caption"
>
<div style="width: 100%;" class="mx-auto" v-if="showFooterLogo()">
<v-img
style="margin: 0 auto;"
:src="require('../assets/logo.svg')"
width="48px"
height="48px"
max-height="48px"
max-width="48px"
contain
></v-img>
</div>
<div class="mx-auto">AyaNova {{ version }}</div>
<div class="mx-auto">
<span class="primary white--text text-caption">{{
copyright
}}</span>
</div>
</a>
</div>
<div v-else style="text-align: center;" class="mx-auto pa-4 mb-1 mb-sm-1">
<a
href="https://ayanova.com"
target="_blank"
style="text-decoration:none"
class="primary white--text text-caption"
>
<div class="mx-auto">AyaNova {{ version }}</div>
<div class="mx-auto">
<span class="primary white--text text-caption">{{
copyright
}}</span>
</div>
</a>
</div>
</v-footer>
</div>
</template>
<script>
/* xeslint-disable */
import { processLogin, processLogout } from "../api/authutil";
import ayaNovaVersion from "../api/ayanova-version";
export default {
data() {
return {
input: {
username: "superuser",
password: "l3tm3in"
},
hasSmallLogo: false,
hasMediumLogo: false,
hasLargeLogo: false,
smallLogoUrl: null,
mediumLogoUrl: null,
largeLogoUrl: null,
errorBadCreds: false,
reveal: false,
formState: { errorBoxMessage: null },
showEvalUsers: false,
selectedTrialUserId: 1,
selectLists: {
trialUsers: [
{
name: "AyaNova SuperUser - all",
l: "superuser",
p: "l3tm3in"
},
{
name: "Accounting",
l: "Accounting",
p: "Accounting"
},
{
name: "Business admin",
l: "BizAdminFull",
p: "BizAdminFull"
},
{
name: "Business admin - limited",
l: "BizAdminLimited",
p: "BizAdminLimited"
},
{
name: "Customer",
l: "CustomerFull",
p: "CustomerFull"
},
{
name: "Customer - limited",
l: "CustomerLimited",
p: "CustomerLimited"
},
{
name: "Dispatcher",
l: "DispatchFull",
p: "DispatchFull"
},
{
name: "Dispatcher - limited",
l: "DispatchLimited",
p: "DispatchLimited"
},
{
name: "Head office",
l: "HeadOffice",
p: "HeadOffice"
},
{
name: "Inventory",
l: "InventoryFull",
p: "InventoryFull"
},
{
name: "Inventory - limited",
l: "InventoryLimited",
p: "InventoryLimited"
},
{
name: "Operations",
l: "OpsAdminFull",
p: "OpsAdminFull"
},
{
name: "Operations - limited",
l: "OpsAdminLimited",
p: "OpsAdminLimited"
},
{
name: "Sales",
l: "SalesFull",
p: "SalesFull"
},
{
name: "Sales - limited",
l: "SalesLimited",
p: "SalesLimited"
},
{
name: "Subcontractor",
l: "SubContractorFull",
p: "SubContractorFull"
},
{
name: "Subcontractor - limited",
l: "SubContractorLimited",
p: "SubContractorLimited"
},
{
name: "Technician",
l: "TechFull",
p: "TechFull"
},
{
name: "Technician - limited",
l: "TechLimited",
p: "TechLimited"
},
{
name: "Translation - Deutsch / German",
l: "de",
p: "de"
},
{
name: "Translation - Español / Spanish",
l: "es",
p: "es"
},
{
name: "Translation - Français / French",
l: "fr",
p: "fr"
}
]
}
};
},
async created() {
let vm = this;
//debugger;
//reset password redirects here with preset creds
//this will help the user identify it and hopefully remember it
if (vm.$route.params.presetLogin) {
vm.input.username = vm.$route.params.presetLogin;
vm.input.password = vm.$route.params.presetPassword;
}
vm.smallLogoUrl = window.$gz.api.logoUrl("small");
vm.mediumLogoUrl = window.$gz.api.logoUrl("medium");
vm.largeLogoUrl = window.$gz.api.logoUrl("large");
window.$gz.eventBus.$emit("menu-change", {
isMain: true,
icon: "",
title: ""
});
try {
let res = await window.$gz.api.get("notify/hello");
if (res.data != null) {
vm.showEvalUsers = res.data.eval;
vm.hasSmallLogo = res.data.sl;
vm.hasMediumLogo = res.data.ml;
vm.hasLargeLogo = res.data.ll;
}
} catch (error) {
//squash it, this isn't critical
}
},
computed: {
copyright() {
return ayaNovaVersion.copyright;
},
version() {
return ayaNovaVersion.version;
}
},
methods: {
showFooterLogo() {
return (
this.showCustomSmallLogo() ||
this.showCustomMediumLogo() ||
this.showCustomLargeLogo()
);
},
showSmallBrandLogo() {
return !this.hasMediumLogo && this.$vuetify.breakpoint.smAndDown;
},
showLargeBrandLogo() {
if (this.showSmallBrandLogo()) {
return false;
}
if (this.showCustomSmallLogo()) {
return false;
}
if (this.showCustomMediumLogo()) {
return false;
}
if (this.showCustomLargeLogo()) {
return false;
}
return true;
},
showCustomSmallLogo() {
//https://vuetifyjs.com/en/features/breakpoints/#breakpoint-service
return this.hasMediumLogo && this.$vuetify.breakpoint.smAndDown;
},
showCustomMediumLogo() {
return this.hasMediumLogo && this.$vuetify.breakpoint.mdOnly;
},
showCustomLargeLogo() {
return this.hasLargeLogo && this.$vuetify.breakpoint.lgAndUp;
},
trialUserSelected(item) {
this.input.password = item.p;
this.input.username = item.l;
},
trialHelpClick: function() {
//open help nav for trial login
window.$gz.eventBus.$emit("menu-click", {
key: "app:help",
data: "ay-start-trial-login"
});
},
onEnterUserName: function() {
//move focus to password
document.getElementsByName("password")[0].focus();
},
async login() {
let vm = this;
if (vm.input.username != "" && vm.input.password != "") {
vm.errorBadCreds = false;
let loggedInWithKnownPassword =
vm.input.username == "superuser" && vm.input.password == "l3tm3in";
try {
let res = await window.$gz.api.upsert(
"auth",
{
login: vm.input.username,
password: vm.input.password
},
true
);
if (res.error) {
//don't expect this to ever get called but just in case
// throw new Error(res.error);
throw new Error(window.$gz.errorHandler.errorToString(res, vm));
}
await processLogin(res.data, loggedInWithKnownPassword);
//check if support and updates has expired and is paid for license and show warning if so
if (
vm.$store.state.globalSettings.maintenanceExpired &&
(vm.$store.state.globalSettings.licenseStatus == 3 ||
vm.$store.state.globalSettings.licenseStatus == 4)
) {
(async function() {
await window.$gz.dialog.displayLTModalNotificationMessage(
"MaintenanceExpiredNote",
"MaintenanceExpired",
"error",
"https://www.ayanova.com/subscriptionexpired.htm"
);
})();
}
let toPath = vm.$route.params.topath; //set in app.vue::mounted
if (toPath != undefined) {
//check if it's an open report link and if so
//trigger that to open in a new window and continue on to normal home page
if (toPath.startsWith("/viewreport")) {
(async function() {
//open report links have a query string /viewreport?oid=[objectid]&rid=[reportid]
let searchParams = new URLSearchParams(vm.$route.params.search);
let objectId = parseInt(searchParams.get("oid"));
let reportId = parseInt(searchParams.get("rid"));
await window.$gz.api.renderReport(objectId, reportId); //objectid,reportid
})();
vm.$router.push(vm.$store.state.homePage);
} else {
//otherwise open the url indicated
vm.$router.push(vm.$route.params.topath);
}
} else {
vm.$router.push(vm.$store.state.homePage);
}
} catch (error) {
//bad creds?
if (
error.message &&
error.message.includes("ErrorUserNotAuthenticated")
) {
vm.errorBadCreds = true;
return;
}
//server closed by server state setting?
if (error.code == 2000 || error.code == 2001) {
vm.formState.errorBoxMessage = error.message;
return;
}
//probably here because server unresponsive.
if (error.message) {
let msg = error.message;
if (
msg.includes("NetworkError") ||
msg.includes("Failed to fetch")
) {
msg =
"Could not connect to AyaNova server at " +
window.$gz.api.APIUrl("") +
"\r\nError: " +
error.message;
}
//this just makes the error a little cleaner to remove the extraneous typeerror
msg = msg.replace(" TypeError:", "");
vm.formState.errorBoxMessage = msg;
return;
}
}
}
}
},
beforeRouteEnter(to, from, next) {
//very important as this in conjunction with the menu options means
//navigation guards work properly by just sending people here
next(() => {
// auth.logout();
processLogout();
next();
});
}
};
</script>