Skip to content

Commit c5cd3a0

Browse files
committed
add protected route
1 parent 1a7856e commit c5cd3a0

File tree

14 files changed

+12285
-0
lines changed

14 files changed

+12285
-0
lines changed

vue-noob-router-2/.gitignore

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
.DS_Store
2+
node_modules
3+
/dist
4+
5+
# local env files
6+
.env.local
7+
.env.*.local
8+
9+
# Log files
10+
npm-debug.log*
11+
yarn-debug.log*
12+
yarn-error.log*
13+
pnpm-debug.log*
14+
15+
# Editor directories and files
16+
.idea
17+
.vscode
18+
*.suo
19+
*.ntvs*
20+
*.njsproj
21+
*.sln
22+
*.sw?

vue-noob-router-2/babel.config.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module.exports = {
2+
presets: [
3+
'@vue/cli-plugin-babel/preset'
4+
]
5+
}

vue-noob-router-2/package-lock.json

Lines changed: 11886 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vue-noob-router-2/package.json

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
{
2+
"name": "vue-noob-router-2",
3+
"version": "0.1.0",
4+
"private": true,
5+
"scripts": {
6+
"serve": "vue-cli-service serve",
7+
"build": "vue-cli-service build",
8+
"lint": "vue-cli-service lint"
9+
},
10+
"dependencies": {
11+
"core-js": "^3.6.5",
12+
"firebase": "^7.17.1",
13+
"vue": "^2.6.11",
14+
"vue-router": "^3.3.4"
15+
},
16+
"devDependencies": {
17+
"@vue/cli-plugin-babel": "~4.4.0",
18+
"@vue/cli-plugin-eslint": "~4.4.0",
19+
"@vue/cli-service": "~4.4.0",
20+
"babel-eslint": "^10.1.0",
21+
"eslint": "^6.7.2",
22+
"eslint-plugin-vue": "^6.2.2",
23+
"vue-template-compiler": "^2.6.11"
24+
},
25+
"eslintConfig": {
26+
"root": true,
27+
"env": {
28+
"node": true
29+
},
30+
"extends": [
31+
"plugin:vue/essential",
32+
"eslint:recommended"
33+
],
34+
"parserOptions": {
35+
"parser": "babel-eslint"
36+
},
37+
"rules": {}
38+
},
39+
"browserslist": [
40+
"> 1%",
41+
"last 2 versions",
42+
"not dead"
43+
]
44+
}
4.19 KB
Binary file not shown.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8" />
5+
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
6+
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
7+
<link rel="icon" href="<%= BASE_URL %>favicon.ico" />
8+
<title><%= htmlWebpackPlugin.options.title %></title>
9+
<link
10+
rel="stylesheet"
11+
href="https://bootswatch.com/4/united/bootstrap.min.css"
12+
/>
13+
</head>
14+
<body>
15+
<noscript>
16+
<strong>
17+
We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work
18+
properly without JavaScript enabled. Please enable it to continue.
19+
</strong>
20+
</noscript>
21+
<div id="app"></div>
22+
<!-- built files will be auto injected -->
23+
</body>
24+
</html>

vue-noob-router-2/src/App.vue

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<template>
2+
<div>
3+
<router-view :isAuthenticated="isAuthenticated" :handleAuth="handleAuth" />
4+
</div>
5+
</template>
6+
7+
<script>
8+
import firebase from "./firebase/firebaseApp";
9+
export default {
10+
name: "App",
11+
data() {
12+
return {
13+
isAuthenticated: false,
14+
};
15+
},
16+
beforeCreate: async function () {
17+
const vm = this;
18+
await firebase.auth().onAuthStateChanged(function (user) {
19+
if (user) {
20+
vm.isAuthenticated = true;
21+
} else {
22+
console.log("User is not authenticated");
23+
}
24+
});
25+
},
26+
methods: {
27+
handleAuth: async function (ev) {
28+
const vm = this;
29+
if (ev.mode === "login") {
30+
try {
31+
await firebase
32+
.auth()
33+
.signInWithEmailAndPassword(ev.email, ev.password);
34+
vm.isAuthenticated = true;
35+
} catch (e) {
36+
return e.message;
37+
}
38+
} else if (ev.mode === "register") {
39+
try {
40+
await firebase
41+
.auth()
42+
.createUserWithEmailAndPassword(ev.email, ev.password);
43+
vm.isAuthenticated = true;
44+
} catch (e) {
45+
return e.message;
46+
}
47+
} else {
48+
try {
49+
await firebase.auth().signOut();
50+
vm.isAuthenticated = false;
51+
} catch (e) {
52+
return e;
53+
}
54+
}
55+
},
56+
},
57+
};
58+
</script>
59+
60+
<style>
61+
</style>
6.69 KB
Loading
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
<template>
2+
<div class="container p-4">
3+
<h3 class="text-center">{{ mode | toUpperCase }}</h3>
4+
<div class="toast" :class="{show: error }" role="alert">
5+
<div class="toast-header">
6+
<strong class="mr-auto text-danger">Error</strong>
7+
<button @click="error = ''" type="button" class="ml-2 mb-1 close">
8+
<span aria-hidden="true">&times;</span>
9+
</button>
10+
</div>
11+
<div class="toast-body">{{ error }}</div>
12+
</div>
13+
<form @submit.prevent="handleSubmit">
14+
<div class="form-group">
15+
<label>Email address</label>
16+
<input
17+
required
18+
v-model="email"
19+
type="email"
20+
class="form-control"
21+
placeholder="Enter Email Address"
22+
/>
23+
</div>
24+
<div class="form-group">
25+
<label>Password</label>
26+
<input
27+
minlength="6"
28+
v-model="password"
29+
type="password"
30+
class="form-control"
31+
placeholder="Password"
32+
/>
33+
</div>
34+
<button
35+
type="submit"
36+
class="btn btn-sm btn-success"
37+
>{{ submitted ? 'loading ...' : mode | toUpperCase }}</button>
38+
<button
39+
@click="changeMode"
40+
type="button"
41+
class="btn btn-sm btn-info mx-2"
42+
>Switch to {{ mode === 'login' ? 'Register': 'Login' }}</button>
43+
</form>
44+
</div>
45+
</template>
46+
47+
<script>
48+
export default {
49+
name: "AppAuthPage",
50+
data() {
51+
return {
52+
email: "",
53+
password: "",
54+
mode: "login",
55+
error: "",
56+
submitted: false,
57+
};
58+
},
59+
filters: {
60+
toUpperCase(value) {
61+
return value.toUpperCase();
62+
},
63+
},
64+
watch: {
65+
error() {
66+
const vm = this;
67+
if (vm.error !== "") {
68+
setTimeout(() => {
69+
vm.error = "";
70+
}, 4000);
71+
} else {
72+
clearTimeout();
73+
}
74+
},
75+
"$attrs.isAuthenticated"() {
76+
if (this.$attrs.isAuthenticated) {
77+
this.$router.push({
78+
name: "Home",
79+
});
80+
}
81+
},
82+
},
83+
methods: {
84+
handleSubmit: async function () {
85+
this.submitted = true;
86+
if (!this.validateEmail(this.email)) {
87+
this.submitted = false;
88+
return (this.error = "Please enter a valid Email Address");
89+
}
90+
const res = await this.$attrs.handleAuth({
91+
email: this.email,
92+
password: this.password,
93+
mode: this.mode,
94+
});
95+
if (res) {
96+
this.submitted = false;
97+
return (this.error = res);
98+
}
99+
this.submitted = false;
100+
this.email = "";
101+
this.password = "";
102+
},
103+
validateEmail(email) {
104+
const reg = new RegExp(
105+
/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
106+
);
107+
return reg.test(email);
108+
},
109+
changeMode() {
110+
this.mode = this.mode === "login" ? "register" : "login";
111+
},
112+
},
113+
};
114+
</script>
115+
116+
<style>
117+
form {
118+
width: 50%;
119+
margin: auto;
120+
}
121+
input,
122+
button {
123+
box-shadow: none !important;
124+
outline: none !important;
125+
}
126+
.toast {
127+
position: absolute;
128+
top: 2em;
129+
right: 2em;
130+
background-color: rgba(216, 155, 155, 0.26);
131+
}
132+
.toast.show {
133+
transition: ease 0.3s;
134+
}
135+
@media screen and (max-width: 768px) {
136+
form {
137+
width: auto;
138+
}
139+
}
140+
</style>
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<template>
2+
<div class="container p-4 bg-light">
3+
<h1 class="text-primary">Home Page</h1>
4+
<hr class="my-3" />
5+
<p class="lead">
6+
Email Address:
7+
<span class="text-dark">{{ email }}</span>
8+
</p>
9+
<button
10+
@click="$attrs.handleAuth({mode: 'signout'})"
11+
class="btn btn-sm btn-warning text-dark"
12+
>Sign out</button>
13+
</div>
14+
</template>
15+
16+
<script>
17+
import firebase from "@/firebase/firebaseApp";
18+
export default {
19+
name: "AppHomePage",
20+
data() {
21+
return {
22+
email: "",
23+
};
24+
},
25+
mounted() {
26+
this.email =
27+
firebase.auth().currentUser && firebase.auth().currentUser.email;
28+
},
29+
watch: {
30+
"$attrs.isAuthenticated"() {
31+
if (!this.$attrs.isAuthenticated) {
32+
this.$router.push({
33+
name: "Auth",
34+
});
35+
}
36+
},
37+
},
38+
beforeRouteEnter: function (to, from, next) {
39+
if (from.name === "Auth") {
40+
next();
41+
} else {
42+
next({
43+
name: "Auth",
44+
});
45+
}
46+
},
47+
};
48+
</script>
49+
50+
<style>
51+
</style>

0 commit comments

Comments
 (0)