Created
November 8, 2019 09:56
-
-
Save Gumball12/4c9e25284e4fd4cdbf2e070a232f5808 to your computer and use it in GitHub Desktop.
SERVERLESS_WITH_OAUTH HANDER_CODE
This file contains hidden or 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
'use strict'; | |
// import modules | |
const _ = require('lodash'); | |
const aws = require('aws-sdk'); | |
const randomEmoji = require('random-emoji'); | |
// aws lambda | |
const lambda = new aws.Lambda({ | |
region: 'ap-northeast-2', | |
}); | |
/* handlers */ | |
/** | |
* xss filtering function | |
* @param {Object} payload payload | |
* @param {Object} payload.body payload body | |
* @param {String} payload.body.target filtering target | |
* @param {Object} payload.body.payload transfer payload | |
* @param {String} payload.body.payload.userId user id | |
* @param {String} payload.body.payload.password user password | |
*/ | |
module.exports.filter = async ({ body }) => { | |
// parse body | |
const { target, payload } = JSON.parse(body); | |
// target branching | |
switch (target) { | |
/** | |
* invoke 'resource-owner' lambda func | |
* @description http 200: Success (return Auth Grant) | |
* @description http 401: Unauthorized user (return message) | |
* @return {String} Auth Grant ID | message | |
*/ | |
case 'resource-owner': { | |
const { Payload } = await lambda.invoke({ | |
FunctionName: process.env.resourceOwner, | |
Payload: JSON.stringify(payload), // with payload | |
}).promise(); | |
// success or error (just payload data) | |
return { | |
statusCode: 200, | |
headers: { | |
'Access-Control-Allow-Origin': '*', | |
'Access-Control-Allow-Credentials': true, | |
}, | |
body: Payload, // auth grant id | |
}; | |
break; | |
} | |
/** | |
* invoke 'authorization-server' lambda func | |
* @description http 200: Success (return Access/Refresh Token) | |
* @description http 401: Unauthorized user (return message) | |
* @return {String} Token | message | |
*/ | |
case 'authorization-server': { | |
const { Payload } = await lambda.invoke({ | |
FunctionName: process.env.authorizationServer, | |
Payload: JSON.stringify(payload), | |
}).promise(); | |
return { | |
statusCode: 200, | |
headers: { | |
'Access-Control-Allow-Origin': '*', | |
'Access-Control-Allow-Credentials': true, | |
}, | |
body: Payload, // token | |
}; | |
break; | |
} | |
/** | |
* invoke 'resource-server' lambda func | |
* @description http 200: Success (return Protected Resource) | |
* @description http 401: Unauthorized user (return message) | |
* @description http 403: Forbidden (return message) | |
* @return {String} Resource | message | |
*/ | |
case 'resource-server': { | |
const { Payload } = await lambda.invoke({ | |
FunctionName: process.env.resourceServer, | |
Payload: JSON.stringify(payload), | |
}).promise(); | |
return { | |
statusCode: 200, | |
headers: { | |
'Access-Control-Allow-Origin': '*', | |
'Access-Control-Allow-Credentials': true, | |
}, | |
body: Payload, // resource | |
}; | |
break; | |
} | |
} | |
}; | |
/** | |
* mocking function for resource owner | |
* @param {Object} payload | |
* @param {String} payload.userId | |
* @param {String} payload.password | |
* @param {Boolean} payload.isRegister | |
* @return {String} Authorization Grant ID | http status code | |
*/ | |
module.exports.resourceOwner = async ({ userId, password, isRegister }) => { | |
if (isRegister) { | |
if (userId !== 'darwin10') { | |
return { | |
statusCode: 201, | |
}; | |
} | |
// error | |
return { | |
statusCode: 401, | |
body: 'Registration failed' | |
}; | |
} | |
// check user id | |
if (userId === 'darwin') { | |
// get auth grant using internal lambda function | |
const { Payload } = await lambda.invoke({ | |
FunctionName: process.env.getGrant, | |
}).promise(); | |
// success | |
return { | |
statusCode: 200, | |
body: JSON.parse(Payload).body.id, // return Authorization Grant ID | |
}; | |
} | |
// error | |
return { | |
statusCode: 401, | |
body: 'Failed to get token', | |
}; | |
}; | |
/** | |
* mocking function for authorization server | |
* @param {Object} payload | |
* @param {String} payload.userId init token mode (optional) | |
* @param {String} payload.refreshToken new token mode (optional) | |
* @param {String} payload.grant auth grant id | |
* @param {String} payload.isExpired is refresh token expired? (optional) | |
* @return {String} access/refresh token | |
*/ | |
module.exports.authorizationServer = async ({ grant, refreshToken, userId, isExpired }) => { | |
let validation = false; | |
// check payload | |
if (grant) { // init token mode | |
validation = (grant === '101204' && userId === 'darwin'); | |
} else { // new token mode | |
validation = (refreshToken === 'zhckdtk-refresh' && userId === 'darwin'); | |
} | |
// validation check | |
if (validation) { | |
// check token is expired | |
if (isExpired) { | |
return { | |
statusCode: 403, // expired | |
body: 'Token has expired', | |
}; | |
} | |
// get token | |
const { Payload } = await lambda.invoke({ | |
FunctionName: process.env.getToken, | |
}).promise(); | |
// success | |
return { | |
statusCode: 200, | |
body: _.at(JSON.parse(Payload).body, ['accessToken', 'refreshToken']), | |
}; | |
} | |
// error | |
return { | |
statusCode: 401, | |
body: 'Failed to get token', | |
}; | |
}; | |
/** | |
* mocking function for resource server | |
* @param {Object} payload | |
* @param {String} payload.accessToken | |
* @param {String} payload.userId | |
* @param {Boolean} payload.isExpired is access token expired? (optional) | |
* @return {String} protected resource | |
*/ | |
module.exports.resourceServer = async ({ accessToken, userId, isExpired }) => { | |
// check token, userid | |
if (accessToken === 'zhckdtk-access' && userId === 'darwin') { | |
// check token is expired | |
if (isExpired) { | |
return { | |
statusCode: 403, // expired token | |
body: 'Token has expired', | |
}; | |
} | |
// get resource | |
const { Payload } = await lambda.invoke({ | |
FunctionName: process.env.getResource, | |
}).promise(); | |
// success | |
return { | |
statusCode: 200, | |
body: JSON.parse(Payload).body.data, | |
}; | |
} | |
// error | |
return { | |
statusCode: 401, | |
body: 'Failed to get resource', | |
}; | |
}; | |
/** | |
* get auth grant | |
* (internal lambda function tool) | |
* @return {Object} grant payload | |
*/ | |
module.exports.getGrant = async () => ({ | |
statusCode: 200, | |
body: { | |
id: '101204', | |
userId: 'darwin', | |
created: _.now(), | |
expired: _.now() + 1000 * 5, // + 5 sec | |
}, | |
}); | |
/** | |
* get access, refresh tokens | |
* (internal lambda function tool) | |
* @return {Object} token | |
*/ | |
module.exports.getToken = async () => ({ | |
statusCode: 200, | |
body: { | |
userId: 'darwin', | |
accessToken: 'zhckdtk-access', | |
refreshToken: 'zhckdtk-refresh', | |
expired_accessToken: _.now() + 1000 * 60 * 60, // + 1 hour | |
expired_refreshToken: _.now() + 1000 * 60 * 60 * 12, // + 12 hour | |
}, | |
}); | |
/** | |
* get resource | |
* (internal lambda func tool) | |
* @return {Object} protected resource | |
*/ | |
module.exports.getResource = async () => ({ | |
statusCode: 200, | |
body: { | |
data: `${randomEmoji.random({ count: 1 })[0].character}-${Math.floor(0xffffff * Math.random())}`, | |
}, | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment