diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 0000000..3c03207 --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +18 diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..99e6073 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,2 @@ +*.yaml +*.yml diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..6344d81 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,9 @@ +{ + "semi": false, + "singleQuote": true, + "trailingComma": "none", + "arrowParens": "always", + "quoteProps": "as-needed", + "bracketSpacing": true, + "bracketSameLine": false +} diff --git a/README.md b/README.md index 8936a40..47c8536 100644 --- a/README.md +++ b/README.md @@ -3,47 +3,52 @@ > This server helps you to simulate auth0 server locally. So, you are able to use the `/tokeninfo` endpoint to verify your token. ## Getting Started -### Prerequisites -* Install [Node.js](http://nodejs.org) - * on OSX use [homebrew](http://brew.sh) `brew install node` - * on Windows use [chocolatey](https://chocolatey.org/) `choco install nodejs` +### Prerequisites + +- Install [Node.js](http://nodejs.org) + - on OSX use [homebrew](http://brew.sh) `brew install node` + - on Windows use [chocolatey](https://chocolatey.org/) `choco install nodejs` ## Installing -* `fork` this repo -* `clone` your fork -* `npm install` to install all dependencies + +- `fork` this repo +- `clone` your fork +- `npm install` to install all dependencies ## Running the app + After you have installed all dependencies you can now run the app. Run `npm start` to start a local server. The port will be displayed to you as `http://0.0.0.0:3333` (or if you prefer IPv6, if you're using `express` server, then it's `http://[::1]:3333/`). - ## API Documentation ### `GET` /token/:username + Returns a token with the given user(username). This token can the be used by your application. ### `POST` /tokeninfo + Returns the data of the token like the username. **Body** + ``` { "id_token": "your-token-kjasdf6ashasl..." } ``` - ## Related Projects -* [express-typescript-boilerplate](https://github.com/w3tecch/express-typescript-boilerplate) - Boilerplate for an restful express-apllication written in TypeScript -* [express-graphql-typescript-boilerplate](https://github.com/w3tecch/express-graphql-typescript-boilerplate) - A starter kit for building amazing GraphQL API's with TypeScript and express by @w3tecch +- [express-typescript-boilerplate](https://github.com/w3tecch/express-typescript-boilerplate) - Boilerplate for an restful express-apllication written in TypeScript +- [express-graphql-typescript-boilerplate](https://github.com/w3tecch/express-graphql-typescript-boilerplate) - A starter kit for building amazing GraphQL API's with TypeScript and express by @w3tecch ## License + [MIT](/LICENSE) - --- -Made with ♥ by Gery Hirschfeld ([@GeryHirschfeld1](https://twitter.com/GeryHirschfeld1)) \ No newline at end of file + +Made with ♥ by Gery Hirschfeld ([@GeryHirschfeld1](https://twitter.com/GeryHirschfeld1)) diff --git a/app.js b/app.js index 1e002c7..ba07b18 100644 --- a/app.js +++ b/app.js @@ -14,8 +14,10 @@ const cert = require('./cert') let issuer = process.env.ISSUER || 'localhost:3333' let jwksOrigin = `https://${issuer}/` const audience = process.env.AUDIENCE || 'https://generic-audience' -const adminCustomClaim = process.env.ADMIN_CUSTOM_CLAIM || 'https://unbound.se/admin' -const emailCustomClaim = process.env.EMAIL_CUSTOM_CLAIM || 'https://unbound.se/email' +const adminCustomClaim = + process.env.ADMIN_CUSTOM_CLAIM || 'https://unbound.se/admin' +const emailCustomClaim = + process.env.EMAIL_CUSTOM_CLAIM || 'https://unbound.se/email' const debug = Debug('app') @@ -37,7 +39,6 @@ const addCustomClaims = (email, customClaims, token) => { ...claim } }, token) - } const signToken = (token) => { @@ -48,7 +49,8 @@ const signToken = (token) => { } // Configure our small auth0-mock-server -app.options('*', cors(corsOpts)) +app + .options('*', cors(corsOpts)) .use(cors()) .use(bodyParser.json({ strict: false })) .use(bodyParser.urlencoded({ extended: true })) @@ -91,26 +93,31 @@ app.post('/oauth/token', (req, res) => { } else if (req.body.code) { const code = req.body.code const session = sessions[code] - let accessToken = signToken(addCustomClaims(session.email, session.customClaims, { - iss: jwksOrigin, - aud: [audience], - sub: 'auth0|' + session.email, - iat: date, - exp: date + 7200, - azp: session.clientId - })) + let accessToken = signToken( + addCustomClaims(session.email, session.customClaims, { + iss: jwksOrigin, + aud: [audience], + sub: 'auth0|' + session.email, + iat: date, + exp: date + 7200, + azp: session.clientId + }) + ) - let idToken = signToken(addCustomClaims(session.email, session.customClaims, { - iss: jwksOrigin, - aud: session.clientId, - nonce: session.nonce, - sub: 'auth0|' + session.email, - iat: date, - exp: date + 7200, - azp: session.clientId, - name: 'Example Person', - picture: 'https://cdn.playbuzz.com/cdn/5458360f-32ea-460e-a707-1a2d26760558/70bda687-cb84-4756-8a44-8cf735ed87b3.jpg' - })) + let idToken = signToken( + addCustomClaims(session.email, session.customClaims, { + iss: jwksOrigin, + aud: session.clientId, + nonce: session.nonce, + sub: 'auth0|' + session.email, + iat: date, + exp: date + 7200, + azp: session.clientId, + name: 'Example Person', + picture: + 'https://cdn.playbuzz.com/cdn/5458360f-32ea-460e-a707-1a2d26760558/70bda687-cb84-4756-8a44-8cf735ed87b3.jpg' + }) + ) debug('Signed token for ' + session.email) @@ -133,9 +140,12 @@ app.get('/token/:email', (req, res) => { debug('No user was given!') return res.status(400).send('user is missing') } - const token = jwt.sign({ - user_id: 'auth0|' + req.params.email - }, privateKey) + const token = jwt.sign( + { + user_id: 'auth0|' + req.params.email + }, + privateKey + ) debug('Signed token for ' + req.params.email) res.json({ token }) }) @@ -160,7 +170,9 @@ app.post('/code', (req, res) => { codeChallenge: req.body.codeChallenge, customClaims: [claim] } - res.redirect(`${req.body.redirect}?domain=${issuer}&code=${code}&state=${encodeURIComponent(state)}`) + res.redirect( + `${req.body.redirect}?code=${code}&state=${encodeURIComponent(state)}` + ) }) app.get('/authorize', (req, res) => { @@ -246,7 +258,12 @@ app.get('/authorize', (req, res) => { }) app.get('/userinfo', (req, res) => { - res.contentType('application/json').send(JSON.stringify({ picture: 'https://cdn.playbuzz.com/cdn/5458360f-32ea-460e-a707-1a2d26760558/70bda687-cb84-4756-8a44-8cf735ed87b3.jpg' })) + res.contentType('application/json').send( + JSON.stringify({ + picture: + 'https://cdn.playbuzz.com/cdn/5458360f-32ea-460e-a707-1a2d26760558/70bda687-cb84-4756-8a44-8cf735ed87b3.jpg' + }) + ) }) app.get('/v2/logout', (req, res) => { @@ -254,9 +271,8 @@ app.get('/v2/logout', (req, res) => { }) app.get('/.well-known/jwks.json', (req, res) => { - res - .contentType('application/json') - .send(JSON.stringify({ + res.contentType('application/json').send( + JSON.stringify({ keys: [ { alg: 'RS256', @@ -270,7 +286,8 @@ app.get('/.well-known/jwks.json', (req, res) => { x5t: thumbprint } ] - })) + }) + ) }) // This route returns the inside of a jwt-token. Your main application @@ -297,7 +314,13 @@ app.post('/issuer', (req, res) => { } issuer = req.body.issuer jwksOrigin = `https://${issuer}/` - const { privateKey: key, certDer: der, thumbprint: thumb, exponent: exp, modulus: mod } = cert(jwksOrigin) + const { + privateKey: key, + certDer: der, + thumbprint: thumb, + exponent: exp, + modulus: mod + } = cert(jwksOrigin) privateKey = key certDer = der thumbprint = thumb @@ -324,7 +347,7 @@ app.post('/api/v2/tickets/password-change', (req, res) => { }) }) -app.use(function(req, res, next) { +app.use(function (req, res, next) { console.log('404', req.path) res.status(404).send('error: 404 Not Found ' + req.path) }) diff --git a/cert.js b/cert.js index 05e69e3..6bc18a3 100644 --- a/cert.js +++ b/cert.js @@ -43,11 +43,7 @@ const PUBLIC_KEY_PEM = 'HwIDAQAB\n' + '-----END PUBLIC KEY-----\n' -const createCertificate = ({ - publicKey, - privateKey, - jwksOrigin - }) => { +const createCertificate = ({ publicKey, privateKey, jwksOrigin }) => { const cert = forge.pki.createCertificate() cert.publicKey = publicKey cert.serialNumber = '123' diff --git a/package.json b/package.json index 6af5d17..77caaee 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,10 @@ "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "dev": "nodemon ./app.js", - "start": "node ./app.js" + "start": "node ./app.js", + "lint:prettier": "prettier --check .", + "lint": "yarn lint:prettier", + "lintfix": "prettier --write --list-different ." }, "author": "", "license": "MIT", @@ -24,5 +27,8 @@ "node-rsa": "^1.1.1", "nodemon": "^2.0.21", "serve-favicon": "^2.4.2" + }, + "devDependencies": { + "prettier": "^2.8.4" } } diff --git a/yarn.lock b/yarn.lock index 965eec3..44f5e84 100644 --- a/yarn.lock +++ b/yarn.lock @@ -714,6 +714,11 @@ picomatch@^2.2.1: resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972" integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw== +prettier@^2.8.4: + version "2.8.4" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.4.tgz#34dd2595629bfbb79d344ac4a91ff948694463c3" + integrity sha512-vIS4Rlc2FNh0BySk3Wkd6xmwxB0FpOndW5fisM5H8hsZSxU2VWVB5CWIkIjWvrHjIhxk2g3bfMKM87zNTrZddw== + process-nextick-args@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa"