Skip to content

Instantly share code, notes, and snippets.

@AlinaNova21
Created October 27, 2016 21:14
Show Gist options
  • Save AlinaNova21/4e2c4298e329846cf3021af690b53fab to your computer and use it in GitHub Desktop.
Save AlinaNova21/4e2c4298e329846cf3021af690b53fab to your computer and use it in GitHub Desktop.
apitoken mod for screeps server
// Add a new function to player sandbox space
// Some Super Secret Secret (32 character hex string)
const secret = Buffer.from('DEADBEEF000000000000000000000000', 'hex')
const jwt = require('./lib/jwt')
module.exports = function (config) {
if (config.engine) {
config.engine.onPlayerSandbox = function (sandbox) {
sandbox.getAPIToken = function () {
let key = generateToken(sandbox.module.user)
sandbox.console.log('API KEY:', key)
}
}
}
if (config.backend) {
const path = require('path')
const authlib = require(path.join(path.dirname(require.main.filename), '../lib/authlib'))
config.backend.router.post('/auth/signin', (req, res) => {
let { email, password } = req.body
try {
if (email != 'token') throw new Error('invalid email')
let data = verifyToken(req.body.password)
authlib.genToken(data.user)
.then(token => {
res.json({ ok: 1, token})
})
} catch(e) {
console.error(e)
res.status(401).json({ error: 'unauthorized' })
}
})
}
}
function sha128 (val) {
return require('crypto').createHash('sha128').update(val).digest()
}
function generateToken (userid) {
let data = {
iat: Date.now(),
user: userid
}
return jwt.encode(data, secret)
}
function verifyToken (token) {
return jwt.decode(token, secret)
}
// From https://github.com/hokaccha/node-jwt-simple
/*
* jwt-simple
*
* JSON Web Token encode and decode module for node.js
*
* Copyright(c) 2011 Kazuhito Hokamura
* MIT Licensed
*/
/**
* module dependencies
*/
var crypto = require('crypto')
/**
* support algorithm mapping
*/
var algorithmMap = {
HS256: 'sha256',
HS384: 'sha384',
HS512: 'sha512',
RS256: 'RSA-SHA256'
}
/**
* Map algorithm to hmac or sign type, to determine which crypto function to use
*/
var typeMap = {
HS256: 'hmac',
HS384: 'hmac',
HS512: 'hmac',
RS256: 'sign'
}
/**
* expose object
*/
var jwt = module.exports
/**
* version
*/
jwt.version = '0.5.0'
/**
* Decode jwt
*
* @param {Object} token
* @param {String} key
* @param {Boolean} noVerify
* @param {String} algorithm
* @return {Object} payload
* @api public
*/
jwt.decode = function jwt_decode (token, key, noVerify, algorithm) {
// check token
if (!token) {
throw new Error('No token supplied')
}
// check segments
var segments = token.split('.')
if (segments.length !== 3) {
throw new Error('Not enough or too many segments')
}
// All segment should be base64
var headerSeg = segments[0]
var payloadSeg = segments[1]
var signatureSeg = segments[2]
// base64 decode and parse JSON
var header = JSON.parse(base64urlDecode(headerSeg))
var payload = JSON.parse(base64urlDecode(payloadSeg))
if (!noVerify) {
var signingMethod = algorithmMap[algorithm || header.alg]
var signingType = typeMap[algorithm || header.alg]
if (!signingMethod || !signingType) {
throw new Error('Algorithm not supported')
}
// Support for nbf and exp claims.
// According to the RFC, they should be in seconds.
if (payload.nbf && Date.now() < payload.nbf * 1000) {
throw new Error('Token not yet active')
}
if (payload.exp && Date.now() > payload.exp * 1000) {
throw new Error('Token expired')
}
// verify signature. `sign` will return base64 string.
var signingInput = [headerSeg, payloadSeg].join('.')
if (!verify(signingInput, key, signingMethod, signingType, signatureSeg)) {
throw new Error('Signature verification failed')
}
}
return payload
}
/**
* Encode jwt
*
* @param {Object} payload
* @param {String} key
* @param {String} algorithm
* @param {Object} options
* @return {String} token
* @api public
*/
jwt.encode = function jwt_encode (payload, key, algorithm, options) {
// Check key
if (!key) {
throw new Error('Require key')
}
// Check algorithm, default is HS256
if (!algorithm) {
algorithm = 'HS256'
}
var signingMethod = algorithmMap[algorithm]
var signingType = typeMap[algorithm]
if (!signingMethod || !signingType) {
throw new Error('Algorithm not supported')
}
// header, typ is fixed value.
var header = { typ: 'JWT', alg: algorithm }
if (options && options.header) {
assignProperties(header, options.header)
}
// create segments, all segments should be base64 string
var segments = []
segments.push(base64urlEncode(JSON.stringify(header)))
segments.push(base64urlEncode(JSON.stringify(payload)))
segments.push(sign(segments.join('.'), key, signingMethod, signingType))
return segments.join('.')
}
/**
* private util functions
*/
function assignProperties (dest, source) {
for (var attr in source) {
if (source.hasOwnProperty(attr)) {
dest[attr] = source[attr]
}
}
}
function verify (input, key, method, type, signature) {
if (type === 'hmac') {
return (signature === sign(input, key, method, type))
}
else if (type == 'sign') {
return crypto.createVerify(method)
.update(input)
.verify(key, base64urlUnescape(signature), 'base64')
}else {
throw new Error('Algorithm type not recognized')
}
}
function sign (input, key, method, type) {
var base64str
if (type === 'hmac') {
base64str = crypto.createHmac(method, key).update(input).digest('base64')
}
else if (type == 'sign') {
base64str = crypto.createSign(method).update(input).sign(key, 'base64')
}else {
throw new Error('Algorithm type not recognized')
}
return base64urlEscape(base64str)
}
function base64urlDecode (str) {
return new Buffer(base64urlUnescape(str), 'base64').toString()
}
function base64urlUnescape (str) {
str += new Array(5 - str.length % 4).join('=')
return str.replace(/\-/g, '+').replace(/_/g, '/')
}
function base64urlEncode (str) {
return base64urlEscape(new Buffer(str).toString('base64'))
}
function base64urlEscape (str) {
return str.replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '')
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment