Skip to content

Commit

Permalink
feat: refs #109860 add auth with github, add component for auth page,…
Browse files Browse the repository at this point in the history
… add dev mongo model
  • Loading branch information
brunoMaurice committed Jul 2, 2019
1 parent 923fb87 commit 91d5a79
Show file tree
Hide file tree
Showing 32 changed files with 4,371 additions and 119 deletions.
7 changes: 6 additions & 1 deletion .env.dist
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,9 @@ MONGO_PORT=27017
MONGO_HOST=0.0.0.0
MONGO_USERNAME=connect
MONGO_PASSWORD=connect
MONGO_DB_NAME=connect
MONGO_DB_NAME=connect

PUBLIC_URL=http://localhost:1337
GITHUB_CLIENT_ID=c262ab4075b97372f8a4
GITHUB_CLIENT_SECRET=ebc1d55c864e0413ef707725840b7035be5ebcb7
AUTH_SECRET=xxxxxx
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ node_modules/
yarn-error.log
.history
.env
logs/
logs/
.DS_Store
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ Then start the docker compose to get a mongo db ready to use
docker-compose -d up
```

Build the react application

```
yarn build
```

The project is ready to run

```
Expand Down
12 changes: 12 additions & 0 deletions babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
module.exports = function(api) {
const presets = [
['@babel/preset-env', { useBuiltIns: 'entry', corejs: '3.0.0' }],
'@babel/preset-react',
];

const plugins = ['@babel/plugin-proposal-class-properties'];

api.cache.never();

return { presets, plugins };
};
4 changes: 3 additions & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ services:
environment:
MONGO_INITDB_ROOT_USERNAME: ${MONGO_USERNAME}
MONGO_INITDB_ROOT_PASSWORD: ${MONGO_PASSWORD}
MONGO_INITDB_DATABASE: ${MONGO_DB_NAME}
MONGO_INITDB_PARSE_DATABASE: ${MONGO_DB_NAME}
MONGO_INITDB_API_DATABASE: ${MONGO_DB_NAME}-api
MONGO_INITDB_SANDBOX_DATABASE: ${MONGO_DB_NAME}-sandbox
mongo-express:
image: mongo-express
ports:
Expand Down
22 changes: 19 additions & 3 deletions docker/init-mongo.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,23 @@
mongo -- "$MONGO_INITDB_DATABASE" <<EOF
mongo -- "$MONGO_INITDB_PARSE_DATABASE" <<EOF
var user = '$MONGO_INITDB_ROOT_USERNAME';
var passwd = '$MONGO_INITDB_ROOT_PASSWORD';
var admin = db.getSiblingDB('admin');
admin.auth(user, passwd);
var table = db.getSiblingDB('$MONGO_INITDB_PARSE_DATABASE');
table.auth(user, passwd);
db.createUser({user: user, pwd: passwd, roles: ["readWrite"]});
EOF

mongo -- "$MONGO_INITDB_API_DATABASE" <<EOF
var user = '$MONGO_INITDB_ROOT_USERNAME';
var passwd = '$MONGO_INITDB_ROOT_PASSWORD';
var table = db.getSiblingDB('$MONGO_INITDB_API_DATABASE');
table.auth(user, passwd);
db.createUser({user: user, pwd: passwd, roles: ["readWrite"]});
EOF

mongo -- "$MONGO_INITDB_SANDBOX_DATABASE" <<EOF
var user = '$MONGO_INITDB_ROOT_USERNAME';
var passwd = '$MONGO_INITDB_ROOT_PASSWORD';
var table = db.getSiblingDB('$MONGO_INITDB_SANDBOX_DATABASE');
table.auth(user, passwd);
db.createUser({user: user, pwd: passwd, roles: ["readWrite"]});
EOF
59 changes: 51 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,29 @@
"description": "",
"scripts": {
"start": "node src/index.js",
"build": "webpack --config webpack.conf.js",
"watch": "DEBUG=connect* nodemon --inspect --exec \"yarn build && yarn start\"",
"db.install": "node src/db/install.js",
"tslint.check": "tslint",
"tslint.fix": "tslint --fix",
"prettier.check": "prettier '{src,../common}/**/*.{js}' --list-different",
"prettier.fix": "prettier '{src,../common}/**/*.{js}' --write",
"test": "jest -c jest.config.integration.js --detectOpenHandles --forceExit"
},
"nodemonConfig": {
"restartable": "rs",
"watch": [
"src/"
],
"env": {
"NODE_ENV": "development"
},
"ext": "js,jsx,json,css",
"ignore": [
"src/front/build/*"
],
"delay": "2500"
},
"prettier": {
"singleQuote": true,
"trailingComma": "all",
Expand All @@ -19,19 +36,45 @@
"author": "Matters",
"license": "ISC",
"dependencies": {
"dotenv": "^8.0.0",
"axios": "0.19.0",
"dotenv": "8.0.0",
"debug": "4.1.1",
"express": "^4.17.1",
"express": "4.17.1",
"jsonwebtoken": "8.5.1",
"moment": "2.24.0",
"mongoose": "5.6.2",
"parse-dashboard": "1.3.3",
"parse-server": "3.4.4",
"parse-server-swagger": "0.1.0",
"winston": "^3.2.1"
"winston": "3.2.1"
},
"devDependencies": {
"jest": "^24.8.0",
"prettier": "^1.18.2",
"tslint": "^5.18.0",
"tslint-config-airbnb": "^5.11.1",
"tslint-config-prettier": "^1.18.0"
"@babel/core": "7.4.5",
"@babel/plugin-proposal-class-properties": "7.4.4",
"@babel/polyfill": "7.4.4",
"@babel/preset-env": "7.4.5",
"@babel/preset-react": "7.0.0",
"babel-loader": "8.0.6",
"copy-webpack-plugin": "5.0.3",
"core-js": "3.1.4",
"css-loader": "3.0.0",
"html-webpack-plugin": "3.2.0",
"jest": "24.8.0",
"js-cookie": "2.2.0",
"jwt-decode": "2.2.0",
"mini-css-extract-plugin": "0.7.0",
"node-sass": "4.12.0",
"nodemon": "1.19.1",
"prettier": "1.18.2",
"react": "16.8.6",
"react-dom": "16.8.6",
"sass-loader": "7.1.0",
"style-loader": "0.23.1",
"tslint": "5.18.0",
"tslint-config-airbnb": "5.11.1",
"tslint-config-prettier": "1.18.0",
"url-loader": "2.0.1",
"webpack": "4.35.0",
"webpack-cli": "3.3.5"
}
}
15 changes: 15 additions & 0 deletions src/api/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const auth = require('./services/auth');
const logger = require('./../logger');

module.exports = srv => {
srv.post('/api/auth', async (req, res) => {
try {
const jwt = await auth.connectUser(req.body.code);

res.send(jwt);
} catch (err) {
logger(err);
res.sendStatus(500);
}
});
};
50 changes: 50 additions & 0 deletions src/api/services/auth.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
const jwt = require('jsonwebtoken');
const moment = require('moment');
const { AUTH_SECRET } = require('../../config');
const github = require('./github');
const Developer = require('./../../db/model/developer');

class Auth {
// Generate a token and send connect link by email
async createUserIfNotExist(userGithub) {
let developer = await Developer.findOne({ githubId: userGithub.id }).exec();

if (!developer) {
developer = new Developer({
login: userGithub.login,
githubId: userGithub.id,
companyName: userGithub.company,
email: userGithub.email,
created_at: new Date(),
updated_at: new Date(),
});

developer = await developer.save();
}

return developer;
}

// Valid a token and return the jwt session
async connectUser(githubCode) {
const githubToken = await github.getAccessToken(githubCode);
const userGithub = await github.getUser(githubToken);
const developer = await this.createUserIfNotExist(userGithub);

const jwtToken = jwt.sign(
{
login: developer.login,
name: userGithub.name,
iat: moment().valueOf(),
exp: moment()
.add(1, 'days')
.valueOf(),
},
AUTH_SECRET,
);

return jwtToken;
}
}

module.exports = new Auth();
33 changes: 33 additions & 0 deletions src/api/services/github.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
const axios = require('axios');
const { GITHUB_CLIENT_ID, GITHUB_CLIENT_SECRET } = require('./../../config');

class Github {
async getAccessToken(code) {
const response = await axios({
method: 'post',
url: 'https://github.com/login/oauth/access_token',
data: {
client_id: GITHUB_CLIENT_ID,
client_secret: GITHUB_CLIENT_SECRET,
code,
},
headers: {
Accept: 'application/json',
},
});

return response.data.access_token;
}

async getUser(token) {
const response = await axios({
method: 'get',
url: 'https://api.github.com/user',
headers: { Authorization: `token ${token}`, Accept: 'application/json' },
});

return response.data;
}
}

module.exports = new Github();
12 changes: 12 additions & 0 deletions src/config/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,15 @@ testConfig(MONGO_PASSWORD, 'MONGO_PASSWORD');
const MONGO_DB_NAME = process.env.MONGO_DB_NAME;
testConfig(MONGO_DB_NAME, 'MONGO_DB_NAME');

const AUTH_SECRET = process.env.AUTH_SECRET;
testConfig(AUTH_SECRET, 'AUTH_SECRET');

const GITHUB_CLIENT_ID = process.env.GITHUB_CLIENT_ID;
testConfig(GITHUB_CLIENT_ID, 'GITHUB_CLIENT_ID');

const GITHUB_CLIENT_SECRET = process.env.GITHUB_CLIENT_SECRET;
testConfig(GITHUB_CLIENT_SECRET, 'GITHUB_CLIENT_SECRET');

module.exports = {
APP_PORT,
APP_PROTOCOL,
Expand All @@ -60,4 +69,7 @@ module.exports = {
MONGO_USERNAME,
MONGO_PASSWORD,
MONGO_DB_NAME,
AUTH_SECRET,
GITHUB_CLIENT_ID,
GITHUB_CLIENT_SECRET,
};
26 changes: 26 additions & 0 deletions src/db/apiClient.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
const mongoose = require('mongoose');
const logger = require('../logger');
const {
MONGO_DB_NAME,
MONGO_HOST,
MONGO_USERNAME,
MONGO_PASSWORD,
MONGO_PORT,
} = require('../config');

mongoose.connect(
`mongodb://${MONGO_USERNAME}:${MONGO_PASSWORD}@${MONGO_HOST}:${MONGO_PORT}/${MONGO_DB_NAME}-api`,
{ useNewUrlParser: true },
);

const db = mongoose.connection;

db.on('error', err => {
logger(`mongo connect error : ${err}`);
});

db.once('open', () => {
logger(`mongo connected on ${MONGO_DB_NAME}-api`);
});

module.exports = mongoose;
35 changes: 35 additions & 0 deletions src/db/install.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
const Developer = require('./model/developer');
const Application = require('./model/application');
const mongoose = require('mongoose');

class MongoInstall {
async init() {}

async exec() {
let developer = new Developer({
login: 'sample',
githubId: 12345,
companyName: 'company',
email: '[email protected]',
created_at: new Date(),
updated_at: new Date(),
});

developer = await developer.save();

let application = new Application({
developerId: developer._id,
name: 'sampleApp',
token: 'superToken',
created_at: new Date(),
updated_at: new Date(),
});

await application.save();

return true;
}
}

const install = new MongoInstall();
install.init().then(async () => await install.exec());
11 changes: 11 additions & 0 deletions src/db/model/application.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
const mongoose = require('../apiClient');

const applicationSchema = new mongoose.Schema({
developerId: mongoose.Schema.Types.ObjectId,
name: String,
token: String,
create_at: { type: Date, default: Date.now },
updated_at: { type: Date, default: Date.now },
});

module.exports = mongoose.model('Application', applicationSchema);
12 changes: 12 additions & 0 deletions src/db/model/developer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
const mongoose = require('../apiClient');

const developerSchema = new mongoose.Schema({
login: String,
githubId: { type: Number, unique: true },
companyName: String,
email: String,
create_at: { type: Date, default: Date.now },
updated_at: { type: Date, default: Date.now },
});

module.exports = mongoose.model('Developer', developerSchema);
Loading

0 comments on commit 91d5a79

Please sign in to comment.