-
Notifications
You must be signed in to change notification settings - Fork 1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: Yukai Huang <yukaihuangtw@gmail.com>
- Loading branch information
Showing
9 changed files
with
217 additions
and
3 deletions.
There are no files selected for viewing
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
'use strict' | ||
|
||
const Router = require('express').Router | ||
const passport = require('passport') | ||
const Eauth = require('express-eauth') | ||
|
||
const config = require('../../config') | ||
const models = require('../../models') | ||
const logger = require('../../logger') | ||
const { | ||
setReturnToFromReferer | ||
} = require('../utils') | ||
|
||
const eauth = module.exports = Router() | ||
|
||
class EAuthStreategy extends passport.Strategy { | ||
constructor (options, verify) { | ||
if (typeof options === 'function') { | ||
verify = options | ||
options = undefined | ||
} | ||
|
||
options = options || {} | ||
|
||
super(options) | ||
|
||
this.name = options.name || 'eauth' | ||
this._verify = verify | ||
this._passReqToCallback = options.passReqToCallback || false | ||
} | ||
|
||
authenticate (req) { | ||
const verified = (error, user, info) => { | ||
if (error) { | ||
return this.error(error) | ||
} | ||
|
||
if (!user) { | ||
return this.fail(info) | ||
} | ||
|
||
this.success(user, info) | ||
} | ||
|
||
try { | ||
if (this._passReqToCallback && req) { | ||
this._verify(req, verified) | ||
} else { | ||
this._verify(verified) | ||
} | ||
} catch (e) { | ||
return this.error(e) | ||
} | ||
} | ||
} | ||
|
||
passport.use(new EAuthStreategy({ | ||
passReqToCallback: true | ||
}, function (req, done) { | ||
const address = req.eauth.recoveredAddress | ||
if (!address) { | ||
return done(new Error('EAuth failed'), null) | ||
} | ||
|
||
// construct profile | ||
const profile = { | ||
provider: 'eauth', | ||
id: `eauth-${address}`, | ||
emails: [] | ||
} | ||
|
||
const stringifiedProfile = JSON.stringify(profile) | ||
models.User.findOrCreate({ | ||
where: { | ||
profileid: address | ||
}, | ||
defaults: { | ||
profile: stringifiedProfile | ||
} | ||
}).spread(function (user, created) { | ||
if (user) { | ||
var needSave = false | ||
if (user.profile !== stringifiedProfile) { | ||
user.profile = stringifiedProfile | ||
needSave = true | ||
} | ||
if (needSave) { | ||
user.save().then(function () { | ||
if (config.debug) { logger.debug('user login: ' + user.id) } | ||
return done(null, user) | ||
}) | ||
} else { | ||
if (config.debug) { logger.debug('user login: ' + user.id) } | ||
return done(null, user) | ||
} | ||
} | ||
}).catch(function (err) { | ||
logger.error('eth auth failed: ' + err) | ||
return done(err, null) | ||
}) | ||
})) | ||
|
||
const { signature, message, address, banner } = config.eauth | ||
const eauthMiddleware = new Eauth({ signature, message, address, banner }) | ||
|
||
eauth.get('/auth/eauth/:Address', eauthMiddleware, function (req, res) { | ||
return req.eauth.message ? res.send(req.eauth.message) : res.status(400).send() | ||
}) | ||
|
||
eauth.post('/auth/eauth/:Message/:Signature', eauthMiddleware, function (req, res, next) { | ||
setReturnToFromReferer(req) | ||
passport.authenticate('eauth', { | ||
successReturnToOrRedirect: true | ||
})(req, res, next) | ||
}) |
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
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
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
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
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
/* global web3, $ */ | ||
|
||
const { serverurl } = require('./config') | ||
|
||
let data | ||
let message | ||
let signature | ||
|
||
$('#eth-auth-login').on('click', function () { | ||
// #region Detect metamask | ||
if (typeof web3 !== 'undefined') { | ||
console.log('web3 is detected.') | ||
if (web3.currentProvider.isMetaMask === true) { | ||
if (web3.eth.accounts[0] === undefined && !web3.currentProvider.enable) { | ||
return window.alert('Please login metamask first.') | ||
} | ||
} | ||
} else { | ||
return window.alert('No web3 detected. Please install metamask') | ||
} | ||
// #endregion | ||
|
||
function authStart () { | ||
return $.get(`${serverurl}/auth/eauth/${web3.eth.accounts[0]}`, res => { | ||
data = '' | ||
message = '' | ||
const method = 'eth_signTypedData' // $('#method')[0].value | ||
if (method === 'personal_sign') { | ||
data = '0x' + Array.from(res).map(x => x.charCodeAt(0).toString(16)).join('') | ||
message = res | ||
} else if (method === 'eth_signTypedData') { | ||
data = res | ||
message = res[1].value | ||
} | ||
|
||
// Call metamask to sign | ||
const from = web3.eth.accounts[0] | ||
const params = [data, from] | ||
web3.currentProvider.sendAsync({ | ||
method, | ||
params, | ||
from | ||
}, async (err, result) => { | ||
if (err) { | ||
return console.error(err) | ||
} | ||
|
||
if (result.error) { | ||
return console.error(result.error) | ||
} | ||
|
||
signature = result.result | ||
|
||
if (message !== null && signature !== null) { | ||
const form = document.createElement('form') | ||
document.body.appendChild(form) | ||
form.method = 'post' | ||
form.action = `${serverurl}/auth/eauth/${message}/${signature}` | ||
form.submit() | ||
} | ||
}) | ||
}).fail(function () { | ||
// TODO: flash error | ||
}) | ||
} | ||
|
||
if (web3.currentProvider.enable) { | ||
web3.currentProvider.enable() | ||
.then(function () { | ||
authStart() | ||
}) | ||
} else if (web3.eth.accounts[0]) { | ||
authStart() | ||
} | ||
}) |
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