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
 | |
| }
 |