· 6 years ago · Jun 14, 2019, 09:38 AM
1<template>
2 <div class="page-wrapper">
3 <iframe
4 v-if="isLogout"
5 v-show="false"
6 :src="`https://${currentUser.InstanceAlias}.awsapps.com/connect/logout`"
7 />
8
9 <div class="login-wrapper">
10 <div class="logo-section">
11 <img src="@/assets/login-logo.png" />
12 </div>
13 <div class="form-wrapper">
14 <div class="form-section">
15 <h1 class="form-header">
16 <!-- {{ isConnected ? "Welcome " : "User Login " }} -->
17 </h1>
18
19 <!-- If nothing is happening -->
20 <div
21 v-if="!isConnected && !isFetchingAuth && !isAuthenticating"
22 key="logging"
23 class="sample logging"
24 >
25 <!-- CUSTOM LOGIN PORTAL -->
26 <div v-if="subdomainData && !isLoadingSubdomain">
27 <img
28 v-if="adminLogoUrl"
29 :src="adminLogoUrl"
30 class="admin-logo-image"
31 />
32 <div class="subdomain-container">
33 <h3
34 v-if="subdomainData"
35 >
36 <span class="company-details">Company:</span>
37 {{ subdomainData.CompanyName }}
38 <br />
39 <span class="company-details">Instance:</span>
40 {{ subdomainData.InstanceAlias }}
41 </h3>
42 </div>
43 </div>
44 <!-- END CUSTOM LOGIN PORTAL -->
45
46 <!-- start loading subdomain data -->
47 <div
48 v-show="isLoadingSubdomain"
49 class="subdomain-loader-wrapper"
50 >
51 <hollow-dots-spinner
52 :animation-duration="1000"
53 :dot-size="15"
54 :dots-num="3"
55 color="#06668E"
56 class="subdomain-loader"
57 />
58 </div>
59
60 <!-- Not a subdomain -->
61 <div>
62 <div class="login-form">
63 <input
64 v-show="!isLoadingSubdomain && subdomainData == null"
65 v-model="instanceId"
66 class="login-input"
67 @on-keyup="onInputKeyUp"
68 @keyup.enter="checkInstance()"
69 placeholder="... Instance Alias"
70 />
71 <button
72 class="auth-btn"
73 @click="checkInstance()"
74 :disabled="!isValidInstance"
75 >
76 <span v-show="!isEnableAwsLogin || isCheckingInstance">
77 <MaterialLoader :size="20" />
78 </span>
79 <span
80 v-show="isEnableAwsLogin && !isCheckingInstance"
81 class="secure-login-text"
82 >
83 <b>Secure Login</b>
84 </span>
85 </button>
86 <div class="error-message">{{ errorMessage }}</div>
87 </div>
88 </div>
89 </div>
90 <div
91 v-if="!isConnected && (isAuthenticating || isFetchingAuth)"
92 key="progress"
93 class="sample progress loading-spinner__container"
94 >
95 <p
96 align="center"
97 class="loading-helper-text loading-helper-wrapper"
98 >
99 {{ loadingLine }}
100 </p>
101
102 <p align="center" class="cancel-button">
103 <i-button v-show="!isFetchingAuth" @click="cleanUp()"
104 >Cancel</i-button
105 >
106 </p>
107 </div>
108 <div
109 v-show="isConnected && currentUser.Groups && agentSummary"
110 key="success"
111 class="sample success"
112 >
113 <div v-show="false">
114 <iframe
115 v-if="isLogout"
116 :src="
117 `https://${
118 currentUser.InstanceAlias
119 }.awsapps.com/connect/logout`
120 "
121 />
122 </div>
123
124 <p align="center">
125 <UserAvatar
126 @avatar-ready="avatarReady"
127 v-if="api.getUser"
128 :user="api.getUser"
129 :custom-style="{
130 borderRadius: '100%',
131 width: '80px',
132 height: '80px'
133 }"
134 custom-class="largeInitials"
135 />
136 </p>
137 <p
138 v-if="
139 agentSummary &&
140 isConnected &&
141 currentUser &&
142 currentUser.IdentityInfo
143 "
144 align="center"
145 class="user-info"
146 >
147 <b>
148 {{ currentUser.IdentityInfo.FirstName }}
149 {{ currentUser.IdentityInfo.LastName }}
150 </b>
151 </p>
152 <div
153 v-if="agentSummary && isConnected"
154 class="agent-summary-wrapper"
155 >
156 <p>
157 <span class="bold-white-text">Account:</span
158 >
159 <b>{{ agentSummary.AWSAccountID }}</b>
160 </p>
161 <div
162 v-if="agentSummary && isConnected"
163 class="agent-summary-wrapper"
164 >
165 <p>
166 <span class="bold-white-text">Account:</span
167 >
168 <b>{{ agentSummary.AWSAccountID }}</b>
169 </p>
170 <p>
171 <span class="bold-white-text">Instance:</span
172 >
173 <b>{{ ccpInstanceId }}</b>
174 </p>
175 <p>
176 <span class="bold-white-text">Username:</span
177 >
178 <b>{{ agentSummary.Username }}</b>
179 </p>
180 <!-- <p>
181 <span style="color:#aaa;font-weight:bolder">Role:</span>
182 <b>{{ agentSummary.Role }}</b>
183 </p>-->
184 </div>
185 <p align="center" v-if="isConnected">
186 <i-button type="primary" size="large" @click="reRoute()"
187 >Go to Dashboard</i-button
188 >
189 </p>
190 </div>
191 <p>
192 <i-button
193 long
194 type="text"
195 class="not-you-button"
196 @click="logout"
197 >Not you?</i-button
198 >
199 </p>
200 </div>
201 <div
202 v-show="isAuthenticating || isFetchingAuth || isHydrating"
203 class="await-login-popup"
204 >
205 <div>
206 <hollow-dots-spinner
207 :animation-duration="1000"
208 :dot-size="15"
209 :dots-num="3"
210 color="#515a6e"
211 class="shower-thought-loader"
212 />
213 </div>
214 <p
215 align="center"
216 class="loading-helper-text shower-thought-text"
217 >
218 {{ showerThought }}
219 </p>
220 <div class="pop-up-dialog-wrapper">
221 <small align="center" class="pop-up-helper">
222 Hint: Make sure popups aren't blocked.
223 <br />
224 </small>
225 </div>
226 </div>
227 <div
228 class="create-account-wrapper"
229 v-if="!(isHydrating || isConnected) && !subdomainData"
230 >
231 <a href="https://dextr.cloud/start-my-trial" class="login-subtext">
232 Create an Account
233 <span class="char">→</span>
234 </a>
235 </div>
236 </div>
237 </div>
238 </div>
239
240 <div class="login-footer">
241 <p align="center" class="ex-links">
242 <a href="https://dextr.cloud/company">About</a>
243 <a href="https://dextr.cloud/privacy">Privacy</a>
244 <a href="https://dextr.cloud/terms">Terms</a>
245 <a href="https://dextr.cloud/contact-us">Help</a>
246 </p>
247 <p align="center" class="copyright-text">
248 © DrVoIP & Dextr | 2018-19
249 </p>
250 </div>
251 </div>
252</template>
253
254<script>
255import Setup from "@/views/master/Setup";
256import { HollowDotsSpinner } from "epic-spinners";
257import { mapGetters } from "vuex";
258import awsconnect from "@/assets/aws-connect.svg";
259import drvoip from "@/assets/aaaa.png";
260import logo from "@/assets/dextr-logo.png";
261import asmrLogo from "@/assets/asm-logo.png";
262import { loadingLines, showerThoughts } from "@/common/random";
263
264import {
265 SET_CURRENT_USER,
266 SET_ACTIVITY,
267 SET_QUEUE_METRICS,
268 SET_HEALTH,
269 SET_TEAM,
270 SET_USERS,
271 IS_FIRST_LOGIN,
272 SET_CONNECTED,
273 NEW_STATE
274} from "@/store/actions.type";
275import ccp from "@/store/plugins/ccp";
276import { Hub, Logger } from "aws-amplify";
277import { API, Auth, graphqlOperation, Storage } from "aws-amplify";
278import * as queries from "@/graphql/queries";
279import * as mutations from "@/graphql/mutations";
280import placeHolderUser from "@/assets/placeholder-user.jpg";
281import UserListItem from "@/components/UserListItem";
282import MaterialLoader from "@/components/MaterialLoader";
283import TheDextrLoader from "@/components/TheDextrLoader";
284
285import _ from "lodash";
286
287export default {
288 components: {
289 HollowDotsSpinner,
290 UserListItem,
291 TheDextrLoader,
292 Setup,
293 MaterialLoader
294 },
295 data() {
296 return {
297 isHydrating: false,
298 isCheckingOnboardingProgress: false,
299 isUpdatingOnboardingProgress: false,
300 isVerifyingCredentials: false,
301 verifiedCredentials: false,
302 onBoardDataStatus: {},
303 onBoardData: {},
304 avatarLoaded: false,
305 cognito_username: "",
306 cognito_password: "",
307 errorMessage: null,
308 isValidInstance: false,
309 avatarUrl: null,
310 detectedSubdomain: null,
311 avatarIsLoading: false,
312 onVisitGrant: false,
313 showLearnMore: false,
314 errorOnLoadUser: false,
315 loadingLine: "",
316 showerThought: "",
317 awsconnect,
318 drvoip,
319 logo,
320 users: [],
321 isDomainAvailable: false,
322 isCheckingSubdomainAvailability: false,
323 isCheckingDone: false,
324 isLogout: false,
325 isCheckingInstance: false,
326 subdomainData: null,
327 isLoadingSubdomain: false,
328 adminLogoUrl: null,
329 inputData: {
330 InstanceId: null,
331 CurrentStepIdx: null,
332 Steps: []
333 },
334 setup: {
335 isLoading: false,
336 showHelper: false,
337 domainName: null,
338 adminName: null,
339 adminMail: null,
340 adminCompany: null,
341 currentStep: 0,
342 accessKey: null,
343 secretKey: null,
344 setupModal: false,
345 steps: [
346 {
347 label: "General Info",
348 description: "You know the drill."
349 },
350 {
351 label: "Choose a login Url",
352 description: "This will be the login URL for your users."
353 },
354 {
355 label: "Grant Access",
356 description: "Create an IAM user with the neccessary permissions."
357 },
358 {
359 label: "Select admin(s)",
360 description: "Promote team-members to admin (default role is agent)"
361 },
362 {
363 label: "Review and Confirm",
364 description: "Does everything look good?"
365 }
366 ]
367 },
368 instanceId: localStorage.getItem("ccpInstanceAlias")
369 };
370 },
371 computed: {
372 asmrLogo() {
373 return asmrLogo;
374 },
375 userPlaceholder() {
376 if (this.avatarUrl) {
377 return this.avatarUrl;
378 }
379
380 return placeHolderUser;
381 },
382 ...mapGetters([
383 "isConnected",
384 "ccpInstanceId",
385 "api",
386 "AWSAgentID",
387 "AWSAccountID",
388 "agentSummary",
389 "isFirstLogin",
390 "currentUser",
391 "agentStates",
392 "agent"
393 ]),
394 helperText() {
395 return this.isAuthenticating
396 ? "Dispatching carrier pigeons"
397 : "Summoning spirits";
398 },
399 isDisabled() {
400 if (
401 this.setup.currentStep == 0 &&
402 (_.isEmpty(this.setup.adminCompany) ||
403 _.isEmpty(this.setup.adminName) ||
404 _.isEmpty(this.setup.adminMail))
405 )
406 return true;
407
408 if (
409 this.setup.currentStep == 1 &&
410 (_.isEmpty(this.setup.domainName) || !this.isDomainAvailable)
411 )
412 return true;
413
414 if (
415 this.setup.currentStep == 2 &&
416 (_.isEmpty(this.setup.accessKey) ||
417 _.isEmpty(this.setup.secretKey) ||
418 !this.verifiedCredentials)
419 )
420 return true;
421
422 return false;
423 },
424 isAuthenticated: {
425 get() {
426 return Auth.currentUserCredentials();
427 }
428 },
429 isAuthenticating: {
430 get() {
431 return this.$store.state.isAuthenticating;
432 },
433 set(v) {
434 this.$store.commit("SET_HYBERNATE", v);
435 }
436 },
437 isFetchingAuth: {
438 get() {
439 return this.$store.state.isFetchingAuthenticating;
440 }
441 },
442 isEnableAwsLogin() {
443 return this.$store.state.enableBtnAws;
444 }
445 },
446 watch: {
447 "setup.domainName": function(n, o) {
448 // Checksubdomain availability
449 this.checkSubdomainAvailability(n);
450 },
451 instanceId: function(n, o) {
452 if (n) this.isValidInstance = n && n.length > 4 ? true : false;
453 },
454 "api.getUser": {
455 handler: function(n, o) {
456 console.log("o: ", o);
457 this.isHydrating = false;
458 if (n.Preferences && n.Preferences.Avatar) {
459 this.getAvatar();
460 }
461 },
462 deep: true
463 },
464 isEnableAwsLogin: function(n, o) {
465 console.log("TESTING");
466 this.checkSubDomain();
467 },
468 agentSummary(agentSummary, oldVal) {
469 console.log("agent summary changed");
470 if (agentSummary && !oldVal) {
471 if (!oldVal || agentSummary.Username !== oldVal.Username) {
472 console.log("CCP Connected - Attempting to login to Cognito");
473 console.log(this.agentSummary);
474 this.cognito_username = `${this.AWSAgentID}-${
475 this.agentSummary.InstanceId
476 }`;
477 this.cognito_password = this.AWSAgentID + "A1!";
478 this.signInCognito(this.agentSummary);
479 // console.log("quannt-1");
480 }
481 }
482 }
483 },
484 mounted() {
485 this.logInAsGuest();
486 console.log(2, this.$route.params);
487 if (
488 this.$route.params.hasOwnProperty("subdomain") &&
489 this.$route.params.subdomain
490 ) {
491 this.isLoadingSubdomain = true;
492 this.detectedSubdomain = this.$route.params.subdomain;
493 console.log("Sub Domain: ", this.detectedSubdomain);
494 }
495
496 console.log("mounted login");
497 this.randomText(1);
498 this.randomText(2);
499
500 if (
501 this.api &&
502 this.api.getUser &&
503 this.api.getUser.Preferences &&
504 this.api.getUser.Preferences.Avatar
505 ) {
506 this.getAvatar();
507 }
508
509 this.isValidInstance =
510 this.instanceId && this.instanceId.length > 4 ? true : false;
511 },
512 methods: {
513 async logInAsGuest() {
514 let username = `guest`;
515 let password = "PasswordFake1!_52434234";
516
517 try {
518 const cognitoUser = await Auth.signIn(username, password);
519 console.log(cognitoUser);
520 this.isEnableAwsLogin = true;
521 return true;
522 } catch (error) {
523 console.log(error);
524 this.isEnableAwsLogin = true;
525 return true;
526 }
527 },
528 avatarReady() {
529 this.avatarLoaded = true;
530 },
531 onInputKeyUp(e) {
532 console.log(e.keyCode);
533 if (e.keyCode === 13) {
534 this.checkInstance();
535 }
536 },
537 openSesame() {
538 this.$router.push("backdoor");
539 },
540 fetchAdminLogo(key) {
541 this.$wait.start("loadingAdminLogoLogin");
542 Storage.get(key, {})
543 .then(pic => {
544 this.adminLogoUrl = pic;
545 this.$wait.end("loadingAdminLogoLogin");
546 })
547 .then(res => console.log(res))
548 .catch(err => {
549 this.$wait.end("loadingAdminLogoLogin");
550 });
551 },
552 checkSubdomainAvailability: _.debounce(function(string) {
553 this.isCheckingDone = false;
554 if (string && string.length >= 4) {
555 this.isCheckingSubdomainAvailability = true;
556 this.$store
557 .dispatch("currentUser/checkSubdomain", string)
558 .then(res => {
559 if (res.data.checkSubdomain == null) {
560 this.isDomainAvailable = true;
561 } else {
562 this.isDomainAvailable = false;
563 }
564 this.isCheckingSubdomainAvailability = false;
565 this.isCheckingDone = true;
566 })
567 .catch(e => {
568 this.isDomainAvailable = false;
569 this.isCheckingSubdomainAvailability = false;
570 this.isCheckingDone = true;
571 });
572 }
573 }, 2000),
574 handleRender() {
575 this.showLearnMore = !this.showLearnMore;
576 },
577 getAvatar() {
578 if (
579 this.api.getUser &&
580 this.api.getUser.Preferences &&
581 this.api.getUser.Preferences.Avatar
582 ) {
583 this.avatarIsLoading = true;
584
585 if (this.api.getUser.Preferences.Avatar) {
586 this.avatarUrl = placeHolderUser;
587 return false;
588 }
589
590 Storage.get(this.api.getUser.Preferences.Avatar, {})
591 .then(pic => {
592 this.avatarIsLoading = false;
593 this.avatarUrl = pic;
594 })
595 .catch(() => {
596 this.avatarIsLoading = false;
597 this.avatarUrl = placeHolderUser;
598 });
599 }
600 },
601 randomText(stage) {
602 console.log(stage);
603 let whichText = stage === 1 ? loadingLines : showerThoughts;
604 let randomNumber = Math.floor(
605 Math.random() * (whichText.length - 1 + 1) + 1
606 );
607
608 let randomLine = whichText[randomNumber - 1];
609
610 if (stage === 1) {
611 this.loadingLine = randomLine;
612 } else {
613 this.showerThought = randomLine;
614 }
615 return randomLine;
616 },
617 onSaveSetup() {
618 this.reRoute();
619 },
620 async stepUp(isPrev) {
621 let baseDomain = "https://go.dextr.cloud/";
622
623 if (isPrev) {
624 if (
625 this.setup.currentStep == 2 &&
626 this.setup.domainName.includes(baseDomain)
627 )
628 this.setup.domainName = this.setup.domainName.replace(
629 /(https:\/\/go\.dextr\.cloud\/)/g,
630 ""
631 );
632 this.setup.currentStep -= 1;
633 return false;
634 } else {
635 if (this.setup.currentStep == 0) {
636 this.setup.currentStep += 1;
637 this.updateOnboarding(0, {
638 StepId: 0,
639 AdminName: this.setup.adminCompany,
640 AdminMail: this.setup.adminName,
641 AdminCompany: this.setup.adminMail
642 });
643 } else if (this.setup.currentStep == 1) {
644 this.setup.bucketName = `dextr-${
645 this.setup.domainName
646 }-${this.makeId()}`;
647
648 this.setup.currentStep += 1;
649 this.updateOnboarding(1, {
650 StepId: 1,
651 DomainName: this.setup.domainName,
652 BucketName: this.this.setup.bucketName
653 });
654 } else if (this.setup.currentStep == 2) {
655 this.setup.isLoading = true;
656 try {
657 console.log(this.setup);
658 await API.graphql(
659 graphqlOperation(mutations.updateUser, {
660 input: {
661 InstanceId: this.currentUser.InstanceId,
662 Username: this.currentUser.Username,
663 AdminCompany: this.setup.adminCompany,
664 AdminName: this.setup.adminName,
665 AdminEmail: this.setup.adminMail.toLowerCase(),
666 SubDomain: this.setup.domainName.toLowerCase(),
667 Region: this.agentSummary.Region,
668 BucketName: this.setup.bucketName.toLowerCase(),
669 AccessKeyId: this.setup.accessKey.trim().replace("\t", ""),
670 SecretAccessKey: this.setup.secretKey.trim().replace("\t", "")
671 }
672 })
673 );
674
675 let username = `${this.AWSAgentID}-${this.currentUser.InstanceId}`;
676 let password = this.AWSAgentID + "A1!";
677
678 // Sign in and out with cognito
679 await Auth.signOut();
680 await Auth.signIn(username, password);
681
682 Auth.currentSession().then(res =>
683 console.log(res.idToken.payload._accessKeyId)
684 );
685
686 let userQuery = await API.graphql(
687 graphqlOperation(queries.listUsers, {
688 AWSAccountID: this.currentUser.AWSAccountID,
689 InstanceId: this.currentUser.InstanceId
690 })
691 );
692
693 let usersList = userQuery.data.listUsers.items.filter(user => {
694 console.log("USER: ", user);
695 if (user.Username) {
696 return !user.Username.includes("IAM@");
697 }
698 });
699 console.log(usersList);
700 this.setup.isLoading = false;
701 this.users = usersList;
702 this.setup.currentStep += 1;
703 this.updateOnboarding(2, {
704 StepId: 2,
705 AccessKey: this.setup.accessKey,
706 SecretKey: this.setup.secretKey,
707 IsGrantAccessDextr: this.onVisitGrant,
708 IsVerifiedCredentials: this.verifiedCredentials
709 });
710 // this.loadUsers();
711 } catch (error) {
712 console.log(error);
713 // SHOW AN ERROR HERE! "Unable to retrieve user list.... please go back and check securtity keys again...."
714 this.setup.isLoading = false;
715 }
716 console.log("whaaaaat");
717 // } else if (this.setup.currentStep == 3) {
718 // this.setup.currentStep += 1;
719 } else if (this.setup.currentStep == 3) {
720 this.setSubs(this.setup.DomainName || "");
721 this.$router.replace({
722 path: "/dashboard",
723 query: { subdomain: this.setup.domainName }
724 });
725 this.$Spin.show({
726 class: ["one-n-only"],
727 render(h, p) {
728 return h(TheDextrLoader);
729 }
730 });
731 setTimeout(() => {
732 this.$Spin.hide();
733 }, 5000);
734 }
735 return false;
736 }
737 },
738 async loadUsers() {
739 let userQuery = await API.graphql(
740 graphqlOperation(queries.listUsers, {
741 AWSAccountID: this.agentSummary.AWSAccountID,
742 InstanceId: this.agentSummary.InstanceId
743 })
744 );
745
746 let usersList = userQuery.data.listUsers.items.filter(user => {
747 if (user.Username) {
748 return !user.Username.includes("IAM@");
749 }
750 });
751
752 if (usersList) {
753 this.errorOnLoadUser = false;
754 this.users = usersList;
755 } else {
756 this.errorOnLoadUser = true;
757 this.users = [];
758 }
759
760 this.isLoading = false;
761 },
762 async logout() {
763 this.isLogout = true;
764 this.$store.commit(SET_CONNECTED, false);
765
766 try {
767 await Auth.signOut();
768 setTimeout(() => {
769 this.$store.state.isAuthenticating = false;
770 window.location.href = "/";
771 }, 1000);
772 } catch (error) {
773 console.log(error);
774 }
775 },
776 async signInCognito(ccpUser) {
777 return new Promise(async (resolve, reject) => {
778 let username = `${this.AWSAgentID}-${ccpUser.InstanceId}`;
779 let password = this.AWSAgentID + "A1!";
780
781 try {
782 const cognitoUser = await Auth.signIn(username, password);
783 // this.checkSubDomain();
784 // this.checkOnboardingSetup();
785 // this.getOnboardingStatus();
786 resolve(cognitoUser);
787 } catch (error) {
788 console.log(error);
789 if (error.code === "UserNotFoundException") {
790 this.$store.commit(IS_FIRST_LOGIN, true);
791 this.signUpCognito(this.agentSummary);
792 }
793 reject(error);
794 }
795 });
796 },
797 makeId() {
798 var text = "";
799 var possible = "abcdefghijklmnopqrstuvwxyz0123456789";
800
801 for (var i = 0; i < 5; i++)
802 text += possible.charAt(Math.floor(Math.random() * possible.length));
803
804 return text;
805 },
806 signUpCognito(user) {
807 console.log("SIGN-UP USER TRIGGERED");
808 console.log(user);
809 let username = `${this.AWSAgentID}-${user.InstanceId}`;
810 let password = this.AWSAgentID + "A1!";
811 let AWSAccountID = this.AWSAccountID;
812 let InstanceId = user.InstanceId;
813 let Username = user.Username;
814 let email = "noemail@dextr.cloud";
815 Auth.signUp({
816 username,
817 password,
818 attributes: {
819 email,
820 "custom:AWSAccountID": AWSAccountID,
821 "custom:InstanceId": InstanceId,
822 "custom:Username": Username
823 }
824 })
825 .then(async res => {
826 await this.createUser(this.agentSummary);
827 await this.signInCognito(this.agentSummary);
828 })
829 .catch(err => {
830 if (err.code === "UsernameExistsException") {
831 this.signInCognito(this.agentSummary);
832 } else {
833 console.log(err);
834 }
835 });
836 },
837 reRoute() {
838 let routeQuery = this.$cookie.get("dextr_subdomain");
839 this.$store.dispatch("detectWebRTC", null, { root: 1 });
840 if (routeQuery) {
841 this.$router.replace({
842 path: "/dashboard",
843 query: { subdomain: routeQuery }
844 });
845 } else {
846 this.$router.replace({ path: "/dashboard" });
847 }
848
849 this.$Spin.show({
850 class: ["one-n-only"],
851 render(h, p) {
852 return h(TheDextrLoader);
853 }
854 });
855 setTimeout(() => {
856 this.$Spin.hide();
857 }, 5000);
858 },
859 cleanUp() {
860 localStorage.removeItem("connectPopupManager::connect::loginPopup");
861 this.isAuthenticating = false;
862 },
863 onGrantAccessDextr() {
864 let cfUrl = `https://console.aws.amazon.com/cloudformation/home?region=${
865 this.agentSummary.Region
866 }#/stacks/create/review?templateURL=https://s3.amazonaws.com/dextr-${
867 this.agentSummary.Region
868 }/dextr-cp.template&stackName=dextr-${
869 this.agentSummary.InstanceId
870 }¶m_RecordingBucket=${this.setup.bucketName.toLowerCase()}
871 ¶m_CognitoU=${this.cognito_username}¶m_InstanceId=${
872 this.InstanceId
873 }¶m_CognitoP=${this.cognito_password}`;
874
875 console.log("cfUrl: ", cfUrl);
876
877 let xWin = window.open(cfUrl, "_blank");
878 xWin.focus();
879 this.onVisitGrant = true;
880 },
881 openAwsCloudFormationSetup() {
882 alert("Cloud Formation Setup");
883 },
884 async checkInstance() {
885 try {
886 if (!this.instanceId) {
887 this.$Notice.warning({
888 title: "Please enter Instance Alias."
889 });
890 return false;
891 }
892
893 this.isCheckingInstance = true;
894
895 let isValidAlias = await API.graphql(
896 graphqlOperation(queries.verifyInstance, {
897 CcpUrl: this.instanceId
898 })
899 );
900
901 console.log(isValidAlias);
902
903 if (!isValidAlias.data.verifyInstance.isValid) {
904 this.errorMessage = `${
905 this.instanceId
906 } is not valid. Please check the spelling and try again.`;
907 this.isCheckingInstance = false;
908 return false;
909 }
910 if (!isValidAlias.data.verifyInstance.OnboardingComplete) {
911 this.errorMessage = `${
912 this.instanceId
913 } - Your account has been authenticated with Amazon, but has not been onboarded with Dextr yet. Please get started with the Create an Account link below.`;
914 this.isCheckingInstance = false;
915 return false;
916 }
917
918 this.$store.commit("SET_CCP_INSTANCE_ALIAS", this.instanceId);
919 setTimeout(() => {
920 this.isCheckingInstance = false;
921 }, 3000);
922 this.awsAuthenticate();
923 } catch (error) {
924 console.log(error);
925 this.$Notice.warning({
926 title: `${
927 this.instanceId
928 } is not valid. Please check the spelling and try again.`
929 });
930 this.isCheckingInstance = false;
931 return false;
932 }
933 },
934 async awsAuthenticate() {
935 this.cleanUp();
936 localStorage.setItem("ccpInstanceAlias", this.ccpInstanceId);
937 ccp(this.$store);
938 this.isHydrating = true;
939 this.isAuthenticating = true;
940 const url = `https://${this.ccpInstanceId}.awsapps.com/connect/ccp#/`;
941 const title = `DrVoIP - ${this.ccpInstanceId}`;
942 this.centerPopup(url, title, 400, 573);
943 },
944 createUser(agent) {
945 return new Promise(async (resolve, reject) => {
946 console.log("CREATE USER");
947 console.log(agent);
948
949 const defaultPreferences = {
950 Preferences: {
951 Avatar: null,
952 Theme: "default",
953 DashboardCards: this.$store.state.dashboardCards
954 }
955 };
956
957 const newUser = {
958 ...agent,
959 ...defaultPreferences,
960 Queues: this.agent.configuration.routingProfile.queues.map(queue => {
961 return queue.queueARN;
962 })
963 };
964
965 console.log(newUser);
966
967 try {
968 resolve(
969 await API.graphql(
970 graphqlOperation(mutations.createUser, { input: newUser })
971 )
972 );
973 } catch (error) {
974 console.log(error);
975 reject(error);
976 }
977 });
978 },
979 centerPopup(url, title, w, h) {
980 // Fixes dual-screen position
981 let dualScreenLeft =
982 window.screenLeft != undefined ? window.screenLeft : window.screenX;
983 let dualScreenTop =
984 window.screenTop != undefined ? window.screenTop : window.screenY;
985
986 let width = window.innerWidth
987 ? window.innerWidth
988 : document.documentElement.clientWidth
989 ? document.documentElement.clientWidth
990 : screen.width;
991 let height = window.innerHeight
992 ? window.innerHeight
993 : document.documentElement.clientHeight
994 ? document.documentElement.clientHeight
995 : screen.height;
996
997 let left = width / 1.2 - w / 1.2 + dualScreenLeft;
998 let top = height / 2 - h / 2 + dualScreenTop;
999 window.globalWindow = window.open(
1000 url,
1001 title,
1002 `toolbar=no, width=400, height=573, top=${top}, left=${left}`
1003 );
1004
1005 // Puts focus on the newWindow
1006 if (window.focus) {
1007 window.globalWindow.focus();
1008 }
1009 },
1010 checkSubDomain() {
1011 console.log(1, this.detectedSubdomain);
1012 if (this.detectedSubdomain) {
1013 this.isLoadingSubdomain = true;
1014 this.$store
1015 .dispatch("currentUser/checkSubdomain", this.detectedSubdomain)
1016 .then(res => {
1017 console.log(res);
1018 this.instanceId = res.data.checkSubdomain.InstanceAlias;
1019 this.subdomainData = res.data.checkSubdomain;
1020 this.setSubs(res.data.checkSubdomain.DomainName);
1021 this.isLoadingSubdomain = false;
1022 if (this.subdomainData.AdminLogo)
1023 this.fetchAdminLogo(this.subdomainData.AdminLogo);
1024 this.isValidInstance =
1025 this.instanceId && this.instanceId.length > 4 ? true : false;
1026 })
1027 .catch(err => {
1028 console.log(err);
1029 this.$Notice.error({
1030 title: "Something went wrong, kindly refresh."
1031 });
1032 this.subdomainData = null;
1033 this.isLoadingSubdomain = false;
1034 this.clearSubs();
1035 this.isValidInstance =
1036 this.instanceId && this.instanceId.length > 4 ? true : false;
1037 });
1038 }
1039 this.clearSubs();
1040 },
1041 clearSubs() {
1042 if (this.$cookie.get("dextr_subdomain"))
1043 this.$cookie.delete("dextr_subdomain");
1044 },
1045 setSubs(sub) {
1046 console.log(sub);
1047 this.$cookie.set("dextr_subdomain", sub.toLowerCase(), { expires: "1M" });
1048 },
1049 async getOnboardingStatus() {
1050 try {
1051 let res = await this.$store.dispatch(
1052 "getOnboardingStatus",
1053 {
1054 InstanceId: this.agentSummary.InstanceId
1055 },
1056 { root: 1 }
1057 );
1058 console.log("Checked onboarding status", res.getOnboardingStatus);
1059 this.onBoardDataStatus = res.getOnboardingStatus;
1060 } catch (e) {
1061 console.log(e);
1062 } finally {
1063 }
1064 },
1065 async updateOnboarding(step, stepData) {
1066 try {
1067 this.isUpdatingOnboardingProgress = true;
1068
1069 let payload = {
1070 input: this.inputData
1071 };
1072
1073 payload.input.InstanceId = this.agentSummary.InstanceId;
1074 payload.input.CurrentStepIdx = step;
1075
1076 if (payload.input.Steps.length > 0) {
1077 payload.input.Steps.push(stepData);
1078 } else {
1079 let found = false;
1080
1081 for (let index = 0; index < payload.input.Steps.length; index++) {
1082 if (payload.input.Steps[index].StepId == stepData.StepId) {
1083 payload.input.Steps.splice(index, 1, stepData);
1084 found = true;
1085 break;
1086 }
1087 }
1088
1089 if (!found) payload.input.Steps.push(stepData);
1090 }
1091
1092 let res = await this.$store.dispatch("updateOnboarding", payload);
1093 console.log("Updated onboarding.", res.updateOnboarding);
1094 } catch (e) {
1095 console.log(e);
1096 } finally {
1097 this.isUpdatingOnboardingProgress = false;
1098 }
1099 },
1100 supplyData(steps, step, prop) {
1101 for (let index = 0; index < steps.length; index++) {
1102 if (steps[index].StepId == step) return steps[index][prop];
1103 }
1104 return null;
1105 },
1106 async onVerifyCreds() {
1107 if (this.setup.secretKey && this.setup.accessKey) {
1108 try {
1109 this.isVerifyingCredentials = true;
1110 let res = await this.$store.dispatch(
1111 "verifyCreds",
1112 {
1113 input: {
1114 InstanceId: this.agentSummary.InstanceId,
1115 Creds: {
1116 Access: this.setup.accessKey,
1117 Region: this.agentSummary.Region,
1118 Secret: this.setup.secretKey
1119 }
1120 }
1121 },
1122 { root: 1 }
1123 );
1124 console.log("Verify Credential", res.verifyCreds);
1125 this.verifiedCredentials = res.verifyCreds.IsValid || false;
1126 } catch (e) {
1127 console.log("Error", e);
1128 this.verifiedCredentials = false;
1129 } finally {
1130 this.isVerifyingCredentials = false;
1131 }
1132 } else {
1133 this.$Notice.info({
1134 title: "Please enter Secret and Access Keys."
1135 });
1136 }
1137 },
1138 async checkOnboardingSetup() {
1139 try {
1140 this.isCheckingOnboardingProgress = true;
1141 let res = await this.$store.dispatch(
1142 "checkOnboardingProgress",
1143 {
1144 InstanceId: this.agentSummary.InstanceId
1145 },
1146 { root: 1 }
1147 );
1148 console.log("Checked onboarding.", res.getOnboarding);
1149 this.onBoardData = res.getOnboarding;
1150 this.setup.currentStep = this.onBoardData.CurrentStepIdx + 1;
1151 this.setup.adminName = this.supplyData(
1152 this.onBoardData.Steps,
1153 0,
1154 "AdminName"
1155 );
1156 this.setup.adminMail = this.supplyData(
1157 this.onBoardData.Steps,
1158 0,
1159 "AdminMail"
1160 );
1161 this.setup.adminCompany = this.supplyData(
1162 this.onBoardData.Steps,
1163 0,
1164 "AdminCompany"
1165 );
1166 this.setup.domainName = this.supplyData(
1167 this.onBoardData.Steps,
1168 1,
1169 "DomainName"
1170 );
1171 this.setup.accessKey = this.supplyData(
1172 this.onBoardData.Steps,
1173 2,
1174 "AccessKey"
1175 );
1176 this.setup.secretKey = this.supplyData(
1177 this.onBoardData.Steps,
1178 2,
1179 "SecretKey"
1180 );
1181 this.setup.bucketName = this.supplyData(
1182 this.onBoardData.Steps,
1183 2,
1184 "BucketName"
1185 );
1186 this.verifiedCredentials = this.supplyData(
1187 this.onBoardData.Steps,
1188 2,
1189 "IsVerifiedCredentials"
1190 );
1191
1192 if (this.setup.secretKey && this.setup.accessKey)
1193 this.onVisitGrant = true;
1194
1195 console.log(this.setup);
1196 } catch (e) {
1197 console.log(e);
1198 } finally {
1199 this.isCheckingOnboardingProgress = false;
1200 }
1201 }
1202 }
1203};
1204</script>
1205
1206<style lang="scss" scoped>
1207@import url("https://fonts.googleapis.com/css?family=Fugaz+One");
1208.admin-logo-image {
1209 width: 100px;height: auto;margin: 0 auto;display: block;
1210}
1211
1212.subdomain-container {
1213 margin: 0 auto;text-align: left; display: table
1214 h3 {
1215 margin:5px 0 25px;color:rgba(4, 65, 90, 0.71); font-weight:800; font-size: 14px
1216 }
1217}
1218
1219.subdomain-loader-wrapper {
1220 padding: 0 20px; margin:30px 0;
1221 .subdomain-loader {
1222 margin: 0 auto;
1223 }
1224}
1225
1226.secure-login-text {
1227 font-style: italic;
1228}
1229
1230.loading-helper-text {
1231 loading-helper-wrapper {
1232 padding: 10px 20px 0;color:#aaa;
1233 }
1234}
1235
1236.cancel-button {
1237 padding: 10px 0;color:#aaa;
1238}
1239
1240.user-info {
1241 color:rgb(40, 40, 40);margin-bottom:10px;font-size:20px;text-transform: capitalize;
1242}
1243
1244.agent-summary-wrapper {
1245 margin:0 auto 20px;text-align:center;font-size:16px;
1246}
1247
1248.bold-white-text {
1249 color:#aaa;font-weight:bolder;
1250}
1251
1252.not-you-button {
1253 text-decoration:underline;font-size:16px;
1254}
1255
1256.shower-thought-loader {
1257 margin: 0 auto;
1258}
1259
1260.show-thought-text {
1261 color:#aaa; max-width: 300px; margin: 0 auto;
1262}
1263
1264.pop-up-dialog-wrapper {
1265 margin: 0px auto; width: 200px; text-align: center;
1266}
1267
1268.create-account-wrapper {
1269 display: flex; justify-content: flex-end; margin-bottom: 4px;
1270}
1271
1272.char {
1273 font-size: 1.2rem; padding-top: 5px;
1274}
1275
1276.copyright-text {
1277 margin-top:5px;font-size:.7rem;color:#aaa;
1278}
1279
1280.powered-by-amazon {
1281 position: absolute;
1282 bottom: 25px;
1283 left: 50%;
1284 margin-left: -50%;
1285 width: 100%;
1286}
1287
1288.login-with-amzn {
1289 margin-top: 25px;
1290 width: 200px;
1291 border: 1px black solid;
1292}
1293
1294.logging {
1295 padding: 5em 10px 4em;
1296}
1297
1298.success {
1299 padding: 1em 0 3em;
1300}
1301
1302.await-login-popup {
1303 margin-top: 2.5em;
1304}
1305
1306@media (max-width: 320px) {
1307 .logging {
1308 padding: 2em 10px;
1309 }
1310
1311 .login-form button {
1312 font-size: 1rem !important;
1313 padding: 0.8rem !important;
1314 }
1315
1316 .login-input {
1317 margin-bottom: 0.8rem;
1318 }
1319}
1320
1321@media (max-width: 516px) {
1322 .success {
1323 padding: 1em 0 1em;
1324 }
1325
1326 .logo-section {
1327 padding-top: 3rem;
1328 }
1329}
1330
1331@media (max-width: 640px) {
1332 .await-login-popup {
1333 margin-bottom: 2.4em;
1334 }
1335}
1336
1337.logging-enter {
1338 transform: translateX(50%);
1339 opacity: 0;
1340}
1341
1342.logging-enter-active {
1343 transition: all 1s ease;
1344}
1345
1346.logging-enter-to {
1347 opacity: 1;
1348}
1349
1350.logging-leave {
1351 opacity: 1;
1352}
1353
1354.logging-leave-active {
1355 transition: all 1s ease;
1356}
1357
1358.logging-leave-to {
1359 transform: translateX(-50%);
1360 opacity: 0;
1361}
1362
1363.ex-links {
1364 margin-top: 15px;
1365}
1366.ex-links > a {
1367 padding: 0 10px;
1368 color: #06a0de !important;
1369}
1370
1371.page-wrapper {
1372 height: 100vh;
1373 padding-top: 2vh;
1374 width: 100vw;
1375 background-color: #ffffff;
1376 transition: all 0.5s ease-in;
1377 margin: 0;
1378 display: flex;
1379 justify-content: center;
1380 align-items: center;
1381 background: url("../../assets/vertices-bg.jpg") repeat;
1382 -webkit-background-size: cover;
1383 -moz-background-size: cover;
1384 -o-background-size: cover;
1385 background-size: cover;
1386}
1387
1388.login-wrapper {
1389 min-height: 300px;
1390 width: 700px;
1391 background-color: #fff;
1392 margin-top: -10%;
1393 box-shadow: 1px 2px 5px 2px #333;
1394 display: flex;
1395 flex-flow: row;
1396 padding: 1rem 0;
1397 font-family: BlinkMacSystemFont, -apple-system, "Segoe UI", Roboto, Oxygen,
1398 Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", Helvetica,
1399 Arial, sans-serif !important;
1400}
1401
1402@media (max-width: 516px) {
1403 .login-wrapper {
1404 flex-flow: row wrap;
1405 }
1406}
1407
1408.login-subtext {
1409 font-family: BlinkMacSystemFont, -apple-system, "Segoe UI", Roboto, Oxygen,
1410 Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", Helvetica,
1411 Arial, sans-serif !important;
1412 text-decoration: none;
1413 color: #666;
1414 font-size: 0.9rem;
1415}
1416
1417.logo-section {
1418 display: flex;
1419 flex-grow: 6;
1420 justify-content: center;
1421 align-items: center;
1422 padding-left: 3rem;
1423 padding-right: 3rem;
1424}
1425
1426.form-section {
1427 box-shadow: -30px 0 150px -30px #582e69;
1428 padding: 0 20px;
1429 width: 100%;
1430 height: 100%;
1431}
1432
1433.form-wrapper {
1434 flex-grow: 6;
1435 font-family: "Ubuntu", "sans-serif";
1436 margin-right: 15px;
1437}
1438
1439@media (max-width: 516px) {
1440 .form-wrapper {
1441 margin-right: 0px;
1442 }
1443}
1444
1445.form-header {
1446 display: inline-block;
1447 color: #333;
1448 text-align: center;
1449}
1450
1451.login-input {
1452 display: block;
1453 margin-bottom: 1rem;
1454 width: 100%;
1455 height: 3em;
1456 padding: 0.375rem 0.75rem;
1457 font-size: 1rem;
1458 font-weight: 400;
1459 line-height: 1.5;
1460 color: #495057;
1461 background-color: #fff;
1462 background-clip: padding-box;
1463 border: 1px solid #ced4da;
1464 border-radius: 0.25rem;
1465 transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
1466 font-family: BlinkMacSystemFont, -apple-system, "Segoe UI", Roboto, Oxygen,
1467 Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", Helvetica,
1468 Arial, sans-serif;
1469}
1470
1471.login-form button {
1472 font-size: 1.2rem;
1473 display: inline-block;
1474 background-color: #03557d;
1475 color: #fff;
1476 width: 100%;
1477 border: none;
1478 border-radius: 25px;
1479 padding: 1rem;
1480 font-family: BlinkMacSystemFont, -apple-system, "Segoe UI", Roboto, Oxygen,
1481 Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", Helvetica,
1482 Arial, sans-serif !important;
1483}
1484
1485.login-form button:hover {
1486 background-color: #dc3553;
1487 cursor: pointer;
1488}
1489
1490.error-message {
1491 width: 100%;
1492 max-width: 300px;
1493 font-weight: bold;
1494 font-size: 14px;
1495 margin-top: 10px;
1496 word-break: break-word;
1497}
1498
1499.error-text {
1500 font-family: "Roboto", "Helvetica", "Arial", sans-serif;
1501 font-weight: 600;
1502 line-height: 1.5em;
1503 color: #b52e68;
1504 margin: 0 auto;
1505}
1506
1507/* .mlogo {
1508 /* -webkit-filter: invert(100%);
1509 filter: invert(100%);
1510 transition: 1s filter linear, 1s -webkit-filter linear;
1511} */
1512.login-template.authenticated {
1513 background: #ffffff;
1514 background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 304 304' width='304' height='304'%3E%3Cpath fill='%23000000' fill-opacity='0.04' d='M44.1 224a5 5 0 1 1 0 2H0v-2h44.1zm160 48a5 5 0 1 1 0 2H82v-2h122.1zm57.8-46a5 5 0 1 1 0-2H304v2h-42.1zm0 16a5 5 0 1 1 0-2H304v2h-42.1zm6.2-114a5 5 0 1 1 0 2h-86.2a5 5 0 1 1 0-2h86.2zm-256-48a5 5 0 1 1 0 2H0v-2h12.1zm185.8 34a5 5 0 1 1 0-2h86.2a5 5 0 1 1 0 2h-86.2zM258 12.1a5 5 0 1 1-2 0V0h2v12.1zm-64 208a5 5 0 1 1-2 0v-54.2a5 5 0 1 1 2 0v54.2zm48-198.2V80h62v2h-64V21.9a5 5 0 1 1 2 0zm16 16V64h46v2h-48V37.9a5 5 0 1 1 2 0zm-128 96V208h16v12.1a5 5 0 1 1-2 0V210h-16v-76.1a5 5 0 1 1 2 0zm-5.9-21.9a5 5 0 1 1 0 2H114v48H85.9a5 5 0 1 1 0-2H112v-48h12.1zm-6.2 130a5 5 0 1 1 0-2H176v-74.1a5 5 0 1 1 2 0V242h-60.1zm-16-64a5 5 0 1 1 0-2H114v48h10.1a5 5 0 1 1 0 2H112v-48h-10.1zM66 284.1a5 5 0 1 1-2 0V274H50v30h-2v-32h18v12.1zM236.1 176a5 5 0 1 1 0 2H226v94h48v32h-2v-30h-48v-98h12.1zm25.8-30a5 5 0 1 1 0-2H274v44.1a5 5 0 1 1-2 0V146h-10.1zm-64 96a5 5 0 1 1 0-2H208v-80h16v-14h-42.1a5 5 0 1 1 0-2H226v18h-16v80h-12.1zm86.2-210a5 5 0 1 1 0 2H272V0h2v32h10.1zM98 101.9V146H53.9a5 5 0 1 1 0-2H96v-42.1a5 5 0 1 1 2 0zM53.9 34a5 5 0 1 1 0-2H80V0h2v34H53.9zm60.1 3.9V66H82v64H69.9a5 5 0 1 1 0-2H80V64h32V37.9a5 5 0 1 1 2 0zM101.9 82a5 5 0 1 1 0-2H128V37.9a5 5 0 1 1 2 0V82h-28.1zm16-64a5 5 0 1 1 0-2H146v44.1a5 5 0 1 1-2 0V18h-26.1zm102.2 270a5 5 0 1 1 0 2H98v14h-2v-16h124.1zM242 149.9V160h16v34h-16v62h48v48h-2v-46h-48v-66h16v-30h-16v-12.1a5 5 0 1 1 2 0zM53.9 18a5 5 0 1 1 0-2H64V2H48V0h18v18H53.9zm112 32a5 5 0 1 1 0-2H192V0h50v2h-48v48h-28.1zm-48-48a5 5 0 0 1-9.8-2h2.07a3 3 0 1 0 5.66 0H178v34h-18V21.9a5 5 0 1 1 2 0V32h14V2h-58.1zm0 96a5 5 0 1 1 0-2H137l32-32h39V21.9a5 5 0 1 1 2 0V66h-40.17l-32 32H117.9zm28.1 90.1a5 5 0 1 1-2 0v-76.51L175.59 80H224V21.9a5 5 0 1 1 2 0V82h-49.59L146 112.41v75.69zm16 32a5 5 0 1 1-2 0v-99.51L184.59 96H300.1a5 5 0 0 1 3.9-3.9v2.07a3 3 0 0 0 0 5.66v2.07a5 5 0 0 1-3.9-3.9H185.41L162 121.41v98.69zm-144-64a5 5 0 1 1-2 0v-3.51l48-48V48h32V0h2v50H66v55.41l-48 48v2.69zM50 53.9v43.51l-48 48V208h26.1a5 5 0 1 1 0 2H0v-65.41l48-48V53.9a5 5 0 1 1 2 0zm-16 16V89.41l-34 34v-2.82l32-32V69.9a5 5 0 1 1 2 0zM12.1 32a5 5 0 1 1 0 2H9.41L0 43.41V40.6L8.59 32h3.51zm265.8 18a5 5 0 1 1 0-2h18.69l7.41-7.41v2.82L297.41 50H277.9zm-16 160a5 5 0 1 1 0-2H288v-71.41l16-16v2.82l-14 14V210h-28.1zm-208 32a5 5 0 1 1 0-2H64v-22.59L40.59 194H21.9a5 5 0 1 1 0-2H41.41L66 216.59V242H53.9zm150.2 14a5 5 0 1 1 0 2H96v-56.6L56.6 162H37.9a5 5 0 1 1 0-2h19.5L98 200.6V256h106.1zm-150.2 2a5 5 0 1 1 0-2H80v-46.59L48.59 178H21.9a5 5 0 1 1 0-2H49.41L82 208.59V258H53.9zM34 39.8v1.61L9.41 66H0v-2h8.59L32 40.59V0h2v39.8zM2 300.1a5 5 0 0 1 3.9 3.9H3.83A3 3 0 0 0 0 302.17V256h18v48h-2v-46H2v42.1zM34 241v63h-2v-62H0v-2h34v1zM17 18H0v-2h16V0h2v18h-1zm273-2h14v2h-16V0h2v16zm-32 273v15h-2v-14h-14v14h-2v-16h18v1zM0 92.1A5.02 5.02 0 0 1 6 97a5 5 0 0 1-6 4.9v-2.07a3 3 0 1 0 0-5.66V92.1zM80 272h2v32h-2v-32zm37.9 32h-2.07a3 3 0 0 0-5.66 0h-2.07a5 5 0 0 1 9.8 0zM5.9 0A5.02 5.02 0 0 1 0 5.9V3.83A3 3 0 0 0 3.83 0H5.9zm294.2 0h2.07A3 3 0 0 0 304 3.83V5.9a5 5 0 0 1-3.9-5.9zm3.9 300.1v2.07a3 3 0 0 0-1.83 1.83h-2.07a5 5 0 0 1 3.9-3.9zM97 100a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm0-16a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm16 16a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm16 16a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm0 16a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm-48 32a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm16 16a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm32 48a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm-16 16a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm32-16a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm0-32a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm16 32a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm32 16a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm0-16a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm-16-64a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm16 0a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm16 96a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm0 16a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm16 16a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm16-144a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm0 32a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm16-32a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm16-16a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm-96 0a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm0 16a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm16-32a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm96 0a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm-16-64a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm16-16a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm-32 0a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm0-16a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm-16 0a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm-16 0a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm-16 0a3 3 0 1 0 0-6 3 3 0 0 0 0 6zM49 36a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm-32 0a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm32 16a3 3 0 1 0 0-6 3 3 0 0 0 0 6zM33 68a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm16-48a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm0 240a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm16 32a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm-16-64a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm0 16a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm-16-32a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm80-176a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm16 0a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm-16-16a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm32 48a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm16-16a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm0-32a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm112 176a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm-16 16a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm0 16a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm0 16a3 3 0 1 0 0-6 3 3 0 0 0 0 6zM17 180a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm0 16a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm0-32a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm16 0a3 3 0 1 0 0-6 3 3 0 0 0 0 6zM17 84a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm32 64a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm16-16a3 3 0 1 0 0-6 3 3 0 0 0 0 6z'%3E%3C/path%3E%3C/svg%3E");
1515 transition: all 0.5s ease;
1516}
1517
1518.login-template.authenticated .mlogo {
1519 -webkit-filter: invert(0%);
1520 filter: invert(0%);
1521}
1522.login-template.authenticated .txt-lbl {
1523 color: #515a6e;
1524 font-weight: bolder;
1525 letter-spacing: 0.5px;
1526}
1527
1528.logo-bg {
1529 margin: 0 auto;
1530 width: 150px;
1531 height: 120px;
1532 z-index: 1;
1533 position: relative;
1534}
1535
1536.logo-bg img {
1537 z-index: 100;
1538 position: absolute;
1539 left: 50%;
1540 margin-left: -75px;
1541 top: 50%;
1542 margin-top: -50px;
1543}
1544.login-card {
1545 background-color: #f8f8f8;
1546 width: 400px;
1547 min-height: 420px;
1548 display: block;
1549 margin: 0 auto;
1550 position: relative;
1551 border: 1px solid #dadada;
1552 border-top-left-radius: 5px;
1553 border-top-right-radius: 5px;
1554 /* box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19); */
1555}
1556.login-card img {
1557 width: 25px;
1558 height: 25px;
1559 vertical-align: middle;
1560}
1561
1562.logo {
1563 margin: 0 auto;
1564 width: 150px;
1565 vertical-align: middle;
1566}
1567
1568.logo img {
1569 vertical-align: middle;
1570 height: 56px !important;
1571 width: 150px !important;
1572}
1573
1574.card-header-stl {
1575 background: #04415a;
1576 padding-top: 5px;
1577 height: 70px;
1578 border-top-left-radius: 5px;
1579 border-top-right-radius: 5px;
1580 border-bottom: 3px solid #41b883;
1581}
1582.card-header-stl p {
1583 font-family: "Open Sans", sans-serif;
1584 font-size: 40px;
1585 padding: 5px;
1586}
1587
1588.brand-logo {
1589 height: 40px;
1590 position: fixed;
1591 top: 0;
1592 left: 0;
1593 right: 0;
1594 padding: 50px;
1595}
1596
1597.login-footer {
1598 position: fixed;
1599 bottom: 0;
1600 left: 50%;
1601 margin-left: -115px;
1602 width: 230px;
1603 padding: 20px 0;
1604}
1605
1606.loading-helper-text {
1607 font-family: BlinkMacSystemFont, -apple-system, "Segoe UI", Roboto, Oxygen,
1608 Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", Helvetica,
1609 Arial, sans-serif !important;
1610}
1611
1612.blogo {
1613 -webkit-transition: 1s -webkit-filter linear;
1614 -moz-transition: 1s -moz-filter linear;
1615 -moz-transition: 1s filter linear;
1616 -ms-transition: 1s -ms-filter linear;
1617 -o-transition: 1s -o-filter linear;
1618 transition: 1s filter linear, 1s -webkit-filter linear;
1619}
1620
1621.company-details {
1622 color: #888888;
1623 font-weight: 400;
1624 font-size: 14px;
1625}
1626
1627.pop-up-helper {
1628 font-family: BlinkMacSystemFont, -apple-system, "Segoe UI", Roboto, Oxygen,
1629 Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", Helvetica,
1630 Arial, sans-serif !important;
1631 padding: 5px;
1632 font-size: 12px;
1633 font-weight: 600;
1634}
1635.sample {
1636 font-family: BlinkMacSystemFont, -apple-system, "Segoe UI", Roboto, Oxygen,
1637 Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", Helvetica,
1638 Arial, sans-serif !important;
1639}
1640
1641.grayscale {
1642 -webkit-filter: grayscale(100%);
1643 filter: grayscale(100%);
1644}
1645
1646.login-signup-container {
1647 text-align: center;
1648 padding: 20px;
1649}
1650</style>
1651<style>
1652.login-card .ivu-steps .ivu-steps-head {
1653 background: transparent !important;
1654}
1655.v-stl-input .ivu-input {
1656 text-align: left;
1657 background-color: #fff;
1658 font-size: 18px;
1659 font-weight: 100;
1660}
1661.v-stl-input .ivu-input:focus {
1662 text-align: left;
1663 background-color: #eee;
1664}
1665
1666.setup-custom-input input {
1667}
1668
1669.largeInitials > .ivu-avatar-string {
1670 line-height: 75px !important;
1671 font-size: 33px !important;
1672 font-weight: 500;
1673}
1674.auth-btn:focus {
1675 outline: none;
1676}
1677</style>