Skip to content

Commit 272e1bb

Browse files
committed
ADD: Auth
ADD: LoadClassData from firestore
1 parent f7e94d8 commit 272e1bb

File tree

14 files changed

+427
-47
lines changed

14 files changed

+427
-47
lines changed

package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,14 @@
2929
"@nuxtjs/axios": "^5.10.3",
3030
"@nuxtjs/dotenv": "^1.4.1",
3131
"@nuxtjs/pwa": "^3.0.0-0",
32+
"cookieparser": "^0.1.0",
3233
"core-js": "3.6.5",
3334
"cross-env": "^7.0.2",
3435
"dayjs": "^1.8.26",
3536
"express": "^4.17.1",
3637
"firebase": "^7.14.2",
38+
"js-cookie": "^2.2.1",
39+
"jwt-decode": "^2.2.0",
3740
"lodash.clonedeep": "^4.5.0",
3841
"nuxt": "^2.12.2",
3942
"nuxt-svg-loader": "^1.2.0",

src/helpers/index.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import jwtDecode from 'jwt-decode'
2+
const cookieparser = require('cookieparser')
3+
4+
export function getUserFromCookie(req) {
5+
if (process.server && process.static) return
6+
if (!req.headers.cookie) return
7+
8+
if (req.headers.cookie) {
9+
const parsed = cookieparser.parse(req.headers.cookie)
10+
const accessTokenCookie = parsed.access_token
11+
if (!accessTokenCookie) return
12+
13+
const decodedToken = jwtDecode(accessTokenCookie)
14+
if (!decodedToken) return
15+
16+
return decodedToken
17+
}
18+
}
19+
20+
export function getUserFromSession(req) {
21+
console.log('[CHECK-AUTH] - checking if user is stored in session')
22+
return req.session ? req.session.userId : null
23+
}

src/layouts/protected.vue

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
<template>
2+
<v-app>
3+
<v-overlay v-if="loading" color="#F8F9FA" opacity="1" z-index="9999">
4+
<div class="loader">
5+
Loading
6+
</div>
7+
</v-overlay>
8+
<!--
9+
<v-navigation-drawer
10+
v-model="drawer"
11+
:mini-variant="miniVariant"
12+
:clipped="clipped"
13+
fixed
14+
app
15+
>
16+
<v-list>
17+
<v-list-item
18+
v-for="(item, i) in items"
19+
:key="i"
20+
:to="item.to"
21+
router
22+
exact
23+
>
24+
<v-list-item-action>
25+
<v-icon>{{ item.icon }}</v-icon>
26+
</v-list-item-action>
27+
<v-list-item-content>
28+
<v-list-item-title v-text="item.title" />
29+
</v-list-item-content>
30+
</v-list-item>
31+
</v-list>
32+
</v-navigation-drawer>
33+
-->
34+
<v-app-bar fixed app>
35+
<v-toolbar-title>
36+
Editor 4<ruby>年<rt>ねん</rt></ruby> 3<ruby>組<rt>くみ</rt></ruby>
37+
</v-toolbar-title>
38+
<v-spacer />
39+
<v-toolbar-title>
40+
4<ruby>月<rt>がつ</rt></ruby> 3<ruby>日<rt>か</rt></ruby>
41+
</v-toolbar-title>
42+
</v-app-bar>
43+
<v-content style="background-color: #0071c2;">
44+
<v-container class="px-4 py-8">
45+
<nuxt />
46+
</v-container>
47+
</v-content>
48+
<v-footer dark color="#0071c2">
49+
<a href="#" @click="signout">Logout</a>
50+
<span>&copy; Code For Japan {{ new Date().getFullYear() }}</span>
51+
</v-footer>
52+
</v-app>
53+
</template>
54+
55+
<script>
56+
import { mapActions } from 'vuex'
57+
export default {
58+
middleware: 'authenticated',
59+
methods: {
60+
...mapActions('modules/user', ['logout']),
61+
async signout() {
62+
await this.logout()
63+
this.$router.push('/')
64+
// this.logout().then(() => {
65+
// this.$router.push('/')
66+
// }).catch((error) => {
67+
// console.log(error.message)
68+
// })
69+
},
70+
},
71+
data() {
72+
return {
73+
loading: true,
74+
}
75+
},
76+
mounted() {
77+
this.loading = false
78+
},
79+
}
80+
</script>
81+
82+
<style scoped>
83+
.date-icon {
84+
margin-right: 15px;
85+
}
86+
</style>

src/middleware/authenticated.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export default function ({ store, redirect }) {
2+
if (!store.getters['modules/user/isAuthenticated']) {
3+
return redirect('/auth/signin')
4+
}
5+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export default function ({ store, redirect }) {
2+
if (store.getters['modules/user/isAuthenticated']) {
3+
return redirect('/protected')
4+
}
5+
}

src/pages/auth/signin.vue

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
<template>
2+
<section class="container">
3+
<div>
4+
<nuxt-link to="/auth/signup">Not a user? Sign-up</nuxt-link>
5+
</div>
6+
<div>
7+
<form @submit.prevent="submit">
8+
<label for="usernameTxt">Username:</label>
9+
<input id="usernameTxt" v-model="email" type="email" />
10+
<label for="passwordTxt">Password:</label>
11+
<input id="passwordTxt" v-model="password" type="password" />
12+
<button type="submit">Sign In</button>
13+
</form>
14+
<button class="button" @click.prevent="fbGoogleLogin">
15+
Google Login
16+
</button>
17+
<button class="button" @click.prevent="fbGoogleLogout">
18+
Google Logout
19+
</button>
20+
</div>
21+
</section>
22+
</template>
23+
24+
<script>
25+
import { mapActions } from 'vuex'
26+
export default {
27+
data() {
28+
return {
29+
email: '',
30+
password: '',
31+
}
32+
},
33+
middleware: ['handle-login-route'],
34+
methods: {
35+
...mapActions('modules/user', ['login']),
36+
submit() {
37+
const res = this.$auth
38+
.signInWithEmailAndPassword(this.email, this.password)
39+
.catch((error) => {
40+
console.log(error.message)
41+
})
42+
console.log(res)
43+
this.$router.push('/edit')
44+
},
45+
/*
46+
async fbGoogleLogin() {
47+
const { user } = await this.$auth.signInWithPopup(googleProvider)
48+
await this.login(user)
49+
this.$router.push('/protected')
50+
},
51+
async fbGoogleLogout() {
52+
await this.logout()
53+
this.$router.push('/')
54+
}, */
55+
},
56+
}
57+
</script>
58+
59+
<style scoped>
60+
form {
61+
padding: 16px;
62+
}
63+
input[type='text'],
64+
input[type='password'] {
65+
width: 100%;
66+
padding: 12px 20px;
67+
margin: 8px 0;
68+
display: inline-block;
69+
border: 1px solid #ccc;
70+
box-sizing: border-box;
71+
}
72+
/* button {
73+
background-color: #4CAF50;
74+
color: white;
75+
padding: 14px 20px;
76+
margin: 8px 0;
77+
border: none;
78+
cursor: pointer;
79+
width: 100%;
80+
} */
81+
button:hover {
82+
opacity: 0.8;
83+
}
84+
.container {
85+
padding: 16px;
86+
max-width: 400px;
87+
}
88+
</style>

src/pages/auth/signup.vue

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
<template>
2+
<section class="container">
3+
<div>
4+
<nuxt-link to="/auth/signin">Already a user? Sign-in</nuxt-link>
5+
</div>
6+
<div>
7+
<form @submit.prevent="signUp">
8+
<label for="usernameTxt">Username:</label>
9+
<input id="usernameTxt" v-model="email" type="text" />
10+
<label for="passwordTxt">Password:</label>
11+
<input id="passwordTxt" v-model="password" type="password" />
12+
<button type="submit">Sign Up</button>
13+
</form>
14+
</div>
15+
</section>
16+
</template>
17+
18+
<script>
19+
import { mapActions } from 'vuex'
20+
export default {
21+
data() {
22+
return {
23+
email: '',
24+
password: '',
25+
}
26+
},
27+
methods: {
28+
...mapActions('modules/user', ['login']),
29+
async signUp() {
30+
try {
31+
const firebaseUser = await this.$auth.createUserWithEmailAndPassword(
32+
this.email,
33+
this.password
34+
)
35+
await this.writeUserData(firebaseUser.uid, firebaseUser.email)
36+
await this.login(firebaseUser.uid)
37+
await this.$router.push('/edit')
38+
} catch (error) {
39+
console.log(error.message)
40+
}
41+
},
42+
writeUserData(userId, email) {
43+
return this.$firestore.collection('users').set({
44+
email,
45+
})
46+
},
47+
},
48+
}
49+
</script>
50+
51+
<style scoped>
52+
form {
53+
padding: 16px;
54+
}
55+
input[type='text'],
56+
input[type='password'] {
57+
width: 100%;
58+
padding: 12px 20px;
59+
margin: 8px 0;
60+
display: inline-block;
61+
border: 1px solid #ccc;
62+
box-sizing: border-box;
63+
}
64+
button {
65+
background-color: #4caf50;
66+
color: white;
67+
padding: 14px 20px;
68+
margin: 8px 0;
69+
border: none;
70+
cursor: pointer;
71+
width: 100%;
72+
}
73+
button:hover {
74+
opacity: 0.8;
75+
}
76+
.container {
77+
padding: 16px;
78+
max-width: 400px;
79+
}
80+
</style>

src/pages/edit/index.vue

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<template>
2+
<h1>test</h1>
3+
</template>
4+
5+
<script>
6+
export default {
7+
layout: 'protected',
8+
name: 'IndexVue',
9+
}
10+
</script>
11+
12+
<style scoped></style>

src/pages/index.vue

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,23 @@
55
<StudyCard
66
schooltime="1"
77
realtime="9:00 - 10:00"
8-
:content="String(users[0].name)"
8+
:content="classData.classData.Lessons['2020-04-04'][0].Content"
99
subject="国語"
1010
/>
1111
</v-col>
1212
<v-col cols="12" md="6">
1313
<StudyCard
1414
schooltime="2"
1515
realtime="10:00 - 11:00"
16-
:content="String(users[1].name)"
16+
content="Stess"
1717
subject="算数"
1818
/>
1919
</v-col>
2020
<v-col cols="12" md="6">
2121
<StudyCard
2222
schooltime="3"
2323
realtime="12:00 - 13:00"
24-
:content="String(users[2].name)"
24+
content="test"
2525
subject="理科"
2626
/>
2727
</v-col>
@@ -43,7 +43,7 @@ import StudyCard from '@/components/StudyCard'
4343
export default {
4444
components: { StudyCard },
4545
computed: {
46-
...mapGetters(['users']),
46+
...mapGetters('modules/class', ['classData']),
4747
},
4848
}
4949
</script>

src/plugins/auth.js

Lines changed: 0 additions & 10 deletions
This file was deleted.

0 commit comments

Comments
 (0)