Skip to content

Instantly share code, notes, and snippets.

@pongsatt
Created May 20, 2018 15:24
Show Gist options
  • Save pongsatt/f4eb518a5232c5e4bda8dd071c886b66 to your computer and use it in GitHub Desktop.
Save pongsatt/f4eb518a5232c5e4bda8dd071c886b66 to your computer and use it in GitHub Desktop.
<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