Created
May 20, 2018 15:24
-
-
Save pongsatt/f4eb518a5232c5e4bda8dd071c886b66 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<template> | |
<div class="googleyolo"> | |
<v-btn light v-if="!loggedIn && useLoginButton" @click="login">Login</v-btn> | |
<v-menu v-if="user" bottom left offset-y> | |
<v-btn slot="activator" icon large> | |
<v-avatar size="32px"> | |
<img | |
:src="user.picture" | |
alt="profile_picture" | |
> | |
</v-avatar> | |
</v-btn> | |
<v-list> | |
<v-list-tile @click="logout"> | |
<v-list-tile-title>Logout</v-list-tile-title> | |
</v-list-tile> | |
</v-list> | |
</v-menu> | |
</div> | |
</template> | |
<script lang="ts"> | |
import Vue from 'vue'; | |
import IdTokenVerifier from 'idtoken-verifier'; | |
declare global { | |
interface Window { | |
onGoogleYoloLoad: any; | |
} | |
} | |
export default Vue.extend({ | |
name: 'googleyolo', | |
props: { | |
clientid: String, | |
useLoginButton: Boolean | |
}, | |
computed: { | |
loggedIn(): boolean { | |
return this.$store && this.$store.state.user; | |
}, | |
user(): any { | |
return this.$store && this.$store.state.user; | |
} | |
}, | |
methods: { | |
setUser(user?: any) { | |
if (this.$store) { | |
this.$store.commit('setUser', user); | |
} | |
}, | |
setToken(token?: any): boolean | undefined { | |
if (this.$store) { | |
this.$store.commit('setToken', token); | |
} | |
localStorage.setItem('token', token); | |
if (token) { | |
const user = decode(token, this.clientid); | |
this.setUser(user); | |
if (user) { | |
return true; | |
} | |
} else { | |
this.setUser(null); | |
} | |
}, | |
logout() { | |
this.setToken(null); | |
}, | |
login() { | |
if (this.loggedIn) { | |
return; | |
} | |
addScript((googleyolo: any) => { | |
signinOrUp(googleyolo, this.clientid, async (err: any, idToken?: string) => { | |
if (err) { | |
this.logout(); | |
return; | |
} | |
if (idToken) { | |
this.setToken(idToken); | |
} | |
}); | |
}); | |
} | |
}, | |
mounted() { | |
// retrieve user from storage | |
const storedToken = localStorage.getItem('token'); | |
if (this.setToken(storedToken)) { | |
return; | |
} | |
if (!this.useLoginButton || storedToken) { // auto login if token expired | |
this.login(); | |
} | |
} | |
}); | |
const decode = (idToken: string, clientId: string) => { | |
const verifier = new IdTokenVerifier({ | |
audience: clientId | |
}); | |
const decoded = verifier.decode(idToken); | |
const payload = decoded.payload; | |
if (payload && (!payload.exp || payload.exp * 1000 >= new Date().getTime())) { | |
return payload; | |
} | |
}; | |
const signinOrUp = (googleyolo: any, clientId: string, cb: (err: any, idToken?: string) => void) => { | |
const retrievePromise = googleyolo.retrieve({ | |
supportedAuthMethods: [ | |
'https://accounts.google.com', | |
'googleyolo://id-and-password' | |
], | |
supportedIdTokenProviders: [ | |
{ | |
uri: 'https://accounts.google.com', | |
clientId | |
} | |
] | |
}); | |
retrievePromise.then((credential: any) => { | |
if (credential.password) { | |
cb('need a password'); | |
} else { | |
cb(null, credential.idToken); | |
} | |
}, (error: any) => { | |
if (error.type === 'noCredentialsAvailable') { | |
signup(googleyolo, clientId, cb); | |
} | |
}); | |
}; | |
const signup = (googleyolo: any, clientid: string, cb: (err: any, idToken?: string) => void) => { | |
const hintPromise = googleyolo.hint({ | |
supportedAuthMethods: [ | |
'https://accounts.google.com' | |
], | |
supportedIdTokenProviders: [ | |
{ | |
uri: 'https://accounts.google.com', | |
clientId: clientid | |
} | |
] | |
}); | |
hintPromise.then((credential: any) => { | |
cb(null, credential.idToken); | |
}, (error: any) => { | |
cb('error while signup: ' + error); | |
}); | |
}; | |
const addScript = (cb: (googleyolo: any) => void) => { | |
if (document) { | |
const script = document.createElement('script'); | |
script.setAttribute('src', 'https://smartlock.google.com/client'); | |
window.onGoogleYoloLoad = cb; | |
document.head.appendChild(script); | |
} | |
}; | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment