200 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			200 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
|  | 'use strict'; | ||
|  | 
 | ||
|  | var request = require('./request.js'); | ||
|  | var PocketId = require('./pocketid.js'); | ||
|  | var state = {}; | ||
|  | var auths = clearAuths(); | ||
|  | 
 | ||
|  | function $$(sel, el) { | ||
|  | 	if (el) { | ||
|  | 		return el.querySelectorAll(sel) || []; | ||
|  | 	} | ||
|  | 	return document.body.querySelectorAll(sel) || []; | ||
|  | } | ||
|  | 
 | ||
|  | function $(sel, el) { | ||
|  | 	if (el) { | ||
|  | 		return el.querySelector(sel); | ||
|  | 	} | ||
|  | 	return document.body.querySelector(sel); | ||
|  | } | ||
|  | 
 | ||
|  | function clearAuths() { | ||
|  | 	var _auths = { | ||
|  | 		google: { | ||
|  | 			promise: null, | ||
|  | 			idToken: '' | ||
|  | 		} | ||
|  | 	}; | ||
|  | 	_auths.google.promise = new Promise(function (res, rej) { | ||
|  | 		_auths.google.resolve = res; | ||
|  | 		_auths.google.reject = rej; | ||
|  | 	}); | ||
|  | 	return _auths; | ||
|  | } | ||
|  | 
 | ||
|  | window.onSignIn = async function onSignIn(googleUser) { | ||
|  | 	// Useful data for your client-side scripts:
 | ||
|  | 	var profile = googleUser.getBasicProfile(); | ||
|  | 	// Don't send this directly to your server!
 | ||
|  | 	console.log('ID: ' + profile.getId()); | ||
|  | 	console.log('Full Name: ' + profile.getName()); | ||
|  | 	console.log('Given Name: ' + profile.getGivenName()); | ||
|  | 	console.log('Family Name: ' + profile.getFamilyName()); | ||
|  | 	console.log('Image URL: ' + profile.getImageUrl()); | ||
|  | 	console.log('Email: ' + profile.getEmail()); | ||
|  | 
 | ||
|  | 	// The ID token you need to pass to your backend:
 | ||
|  | 	auths.google.idToken = googleUser.getAuthResponse().id_token; | ||
|  | 	console.log('ID Token: ' + auths.google.idToken); | ||
|  | 	auths.google.resolve(auths.google.idToken); | ||
|  | }; | ||
|  | 
 | ||
|  | function setFlow(cont, flow) { | ||
|  | 	$$(cont).forEach(function (el) { | ||
|  | 		el.hidden = true; | ||
|  | 	}); | ||
|  | 	console.log(flow); | ||
|  | 	$(flow).hidden = false; | ||
|  | } | ||
|  | 
 | ||
|  | async function unlock() { | ||
|  | 	var key; | ||
|  | 	try { | ||
|  | 		key = await PocketId.unlock(function () { | ||
|  | 			setFlow('.authn-container', '.authn-unlock'); | ||
|  | 			return new Promise(function (resolve, reject) { | ||
|  | 				window.unlocker = { resolve: resolve, reject: reject }; | ||
|  | 			}); | ||
|  | 		}); | ||
|  | 	} catch (e) { | ||
|  | 		console.error( | ||
|  | 			"Had a key, but couldn't unlock it. TODO: Just send email?" | ||
|  | 		); | ||
|  | 		console.error(e); | ||
|  | 		return; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	setFlow('.authn-container', '.authn-loading'); | ||
|  | 
 | ||
|  | 	if (key) { | ||
|  | 		genTokenWithKey(key); | ||
|  | 		return; | ||
|  | 		await PocketId.createIdToken({ key: key }); | ||
|  | 	} | ||
|  | 
 | ||
|  | 	PocketId.signIdToken(id_token).then(function (resp) { | ||
|  | 		console.log('Response:'); | ||
|  | 		console.log(resp); | ||
|  | 	}); | ||
|  | } | ||
|  | 
 | ||
|  | function genTokenWithKey() { | ||
|  | 	// TODO: generate token
 | ||
|  | 	// TODO: check if the key is still considered valid
 | ||
|  | 	// TODO: generate new key and authorize
 | ||
|  | } | ||
|  | 
 | ||
|  | (async function () { | ||
|  | 	var loc = window.location; | ||
|  | 
 | ||
|  | 	console.log('/new-hashcash?'); | ||
|  | 	var resp = await request({ | ||
|  | 		method: 'POST', | ||
|  | 		url: loc.protocol + '//' + loc.hostname + '/api/new-hashcash' | ||
|  | 	}); | ||
|  | 	console.log(resp); | ||
|  | 
 | ||
|  | 	console.log('/test-hashcash?'); | ||
|  | 	resp = await request({ | ||
|  | 		method: 'POST', | ||
|  | 		url: loc.protocol + '//' + loc.hostname + '/api/test-hashcash' | ||
|  | 	}); | ||
|  | 	console.log(resp); | ||
|  | })(); | ||
|  | 
 | ||
|  | setFlow('.authn-container', '.authn-email'); | ||
|  | 
 | ||
|  | $('.authn-email form').addEventListener('submit', function (ev) { | ||
|  | 	ev.preventDefault(); | ||
|  | 	ev.stopPropagation(); | ||
|  | 	state.email = $('.authn-email [name=username]').value; | ||
|  | 
 | ||
|  | 	setFlow('.authn-container', '.authn-loading'); | ||
|  | 	return PocketId.auth | ||
|  | 		.meta({ email: state.email }) | ||
|  | 		.catch(function (err) { | ||
|  | 			window.alert('Error: ' + err.message); | ||
|  | 		}) | ||
|  | 		.then(function (resp) { | ||
|  | 			// if the user exists, go to the continue screen
 | ||
|  | 			// otherwise go to the new user screen
 | ||
|  | 			console.log('meta:', resp); | ||
|  | 			if (!resp.body.success) { | ||
|  | 				// This is a completely new user
 | ||
|  | 				setFlow('.authn-container', '.authn-new-user'); | ||
|  | 				return; | ||
|  | 			} | ||
|  | 			// The user exists, but this is a new device
 | ||
|  | 			setFlow('.authn-container', '.authn-existing'); | ||
|  | 		}); | ||
|  | }); | ||
|  | 
 | ||
|  | $('.authn-new-user form').addEventListener('submit', function (ev) { | ||
|  | 	ev.preventDefault(); | ||
|  | 	ev.stopPropagation(); | ||
|  | 
 | ||
|  | 	// We don't need to worry about checking if the key exists
 | ||
|  | 	// even if it does, the account has been deactivated
 | ||
|  | 
 | ||
|  | 	setFlow('.authn-container', '.authn-loading'); | ||
|  | 	return PocketId.auth | ||
|  | 		.verify({ scheme: 'mailto:', email: state.email }) | ||
|  | 		.catch(function (err) { | ||
|  | 			window.alert('Error: ' + err.message); | ||
|  | 		}) | ||
|  | 		.then(function (resp) { | ||
|  | 			console.log(resp); | ||
|  | 			localStorage.setItem( | ||
|  | 				'pocketid', // + state.email,
 | ||
|  | 				JSON.stringify({ | ||
|  | 					receipt: resp.body.receipt, | ||
|  | 					email: state.email, | ||
|  | 					createdAt: new Date().toISOString() | ||
|  | 				}) | ||
|  | 			); | ||
|  | 			window.alert("Go check yo' email!"); | ||
|  | 			return PocketId.auth | ||
|  | 				.consume({ | ||
|  | 					email: state.email, | ||
|  | 					receipt: resp.body.receipt | ||
|  | 				}) | ||
|  | 				.then(function (resp) { | ||
|  | 					window.alert('all set!'); | ||
|  | 				}); | ||
|  | 		}); | ||
|  | }); | ||
|  | 
 | ||
|  | var route = window.location.hash.split('/').slice(1); | ||
|  | console.log('route:', route); | ||
|  | switch (route[0]) { | ||
|  | 	case 'verify': | ||
|  | 		var pstate = JSON.parse(localStorage.getItem('pocketid') || '{}'); | ||
|  | 		PocketId.auth | ||
|  | 			.consume({ | ||
|  | 				receipt: pstate.receipt, | ||
|  | 				secret: route[1] | ||
|  | 			}) | ||
|  | 			.then(function (resp) { | ||
|  | 				console.log('token for this device to save:', resp); | ||
|  | 				window.alert('goodness!'); | ||
|  | 			}) | ||
|  | 			.catch(function (e) { | ||
|  | 				console.error(e); | ||
|  | 				window.alert('network error, try again'); | ||
|  | 			}); | ||
|  | 		break; | ||
|  | 	default: | ||
|  | 	// do nothing
 | ||
|  | } |