diff --git a/pm2.json.sample b/pm2.json.sample index fb40873..e9db03c 100644 --- a/pm2.json.sample +++ b/pm2.json.sample @@ -6,11 +6,21 @@ "instances" : 4, "exec_mode" : "cluster_mode", "env": { + "NODE_ENV": "production", "PORT": 5000, "FC_CLIENT_ID": "abcdef", - "FC_CLIENT_SECRET": "123456", "SESSION_SECRET": "foobar", + "DOMAIN": "http://bourse.sgmap.fr", + "FC_CLIENT_SECRET": "123456", + + "DGFIP_HOST": "rvxdusx001.dgfip.finances.gouv.fr", + "DGFIP_BASE_URL": "https://rvxdusx001.dgfip.finances.gouv.fr/courtier/bourse", + "DGFIP_CERT_LOCATION": "/path/to.cert", + "DGFIP_KEY_LOCATION": "/path/to.key", + + "NODE_TLS_REJECT_UNAUTHORIZED": 0, + "SMTP_USER": "abc@yourdomain.com", "SMTP_PASS": "pass", "SMTP_HOST": "yourdomain.com" diff --git a/server/api/connection/connection.controller.js b/server/api/connection/connection.controller.js index a9f25fa..794d2ab 100644 --- a/server/api/connection/connection.controller.js +++ b/server/api/connection/connection.controller.js @@ -1,6 +1,21 @@ 'use strict'; +var https = require('https'); +var fs = require('fs'); + var svair = require('svair-api'); +var request = require('superagent'); + +var config = require('../../config/environment'); + +var agentOptions = { hostname: config.dgfip.host }; + +if (config.dgfip.cert && config.dgfip.key) { + agentOptions.key = fs.readFileSync(config.dgfip.key); + agentOptions.cert = fs.readFileSync(config.dgfip.cert); +} + +var boris = new https.Agent(agentOptions); exports.svair = function(req, res, next) { if (!req.query.numeroFiscal || !req.query.referenceAvis) { @@ -29,3 +44,39 @@ exports.svair = function(req, res, next) { }); } }; + +function fetchData(accessToken, year, done) { + request.get(config.dgfip.baseUrl + '/' + year) + .set('Authorization', 'Bearer ' + accessToken) + .redirects(0) + .agent(boris) + .parse(request.parse.text) + .buffer() + .end(function(err, resp) { + if (err && !err.status) return done(err); + done(null, resp.text); + }); +} + +exports.mockData = function(req, res) { + res.json({ + identites: [{nom: 'DUPONT', prenoms: 'MARCEL'}], + rfr: 0, sitFam:'C', nbPart:'1.0', pac:{nbPac:'0'} + }); +}; + +exports.fc = function(req, res, next) { + if (!req.user || !req.user.accessToken) { + return res.status(401).send({ + code: 401, + message: 'Utilisateur non authentifié' + }); + } + + fetchData(req.user.accessToken, 2013, function(err, result) { + if (err) return next(err); + res.send({ response: result }); + }); +}; + +exports.fetchData = fetchData; diff --git a/server/api/connection/index.js b/server/api/connection/index.js index 10a85e1..453a59e 100644 --- a/server/api/connection/index.js +++ b/server/api/connection/index.js @@ -6,5 +6,7 @@ var controller = require('./connection.controller'); var router = express.Router(); router.get('/svair', controller.svair); +router.get('/fc', controller.fc); +router.get('/mock/2013', controller.mockData); module.exports = router; diff --git a/server/config/environment/index.js b/server/config/environment/index.js index 1ccdd85..2a88820 100644 --- a/server/config/environment/index.js +++ b/server/config/environment/index.js @@ -29,6 +29,18 @@ var all = { domain: process.env.DOMAIN || 'http://localhost:5000', + fc: { + clientId: process.env.FC_CLIENT_ID || 'fc-clientId', + clientSecret: process.env.FC_CLIENT_SECRET || 'fc-clientSecret' + }, + + dgfip: { + host: process.env.DGFIP_HOST, + baseUrl: process.env.DGFIP_BASE_URL || 'http://localhost:5000/api/connection/mock', + cert: process.env.DGFIP_CERT_LOCATION, + key: process.env.DGFIP_KEY_LOCATION + }, + // List of user roles userRoles: ['user', 'admin'], diff --git a/server/oauth/france-connect/index.js b/server/oauth/france-connect/index.js new file mode 100644 index 0000000..62371e0 --- /dev/null +++ b/server/oauth/france-connect/index.js @@ -0,0 +1,25 @@ +'use strict'; + +var express = require('express'); +var passport = require('passport'); + +var router = express.Router(); + +router.get('/', function(req, res, next) { + if (req.user && req.user.accessToken) { + return res.redirect('https://app.franceconnect.gouv.fr/api/v1/logout?force'); + } + + next(); +}, passport.authenticate('france-connect')); + +router.get('/callback', passport.authenticate('france-connect', { failureRedirect: '/' }), function(req, res) { + res.redirect('/nouvelle_demande/vos-ressources'); +}); + +router.get('/logout', function(req, res) { + req.logout(); + res.redirect('https://app.franceconnect.gouv.fr/api/v1/logout?force'); +}); + +module.exports = router; diff --git a/server/oauth/france-connect/passport.js b/server/oauth/france-connect/passport.js new file mode 100644 index 0000000..3861add --- /dev/null +++ b/server/oauth/france-connect/passport.js @@ -0,0 +1,41 @@ +var passport = require('passport'); +var OAuth2Strategy = require('passport-oauth2').Strategy; +var request = require('superagent'); + +exports.setup = function(config) { + var strategy = new OAuth2Strategy({ + authorizationURL: 'https://app.franceconnect.gouv.fr/api/v1/authorize', + tokenURL: 'https://app.franceconnect.gouv.fr/api/v1/token', + clientID: config.fc.clientId, + clientSecret: config.fc.clientSecret, + callbackURL: config.domain + '/oauth/fc/callback', + scope: ['openid', 'profile', 'email', 'address', 'phone', 'dgfip_rfr', 'dgfip_nbpac', 'dgfip_sitfam', 'dgfip_nbpart'], + state: 'foobar' + }, + function(accessToken, refreshToken, profile, done) { + var user = profile; + user.accessToken = accessToken; + done(null, user); + } + + ); + strategy.authorizationParams = function() { + // Pour ne garder que le FI dgfip: + // return { nonce: 'foobar', selected_idp: 'dgfip' }; + return { nonce: 'foobar' }; + }; + + strategy.userProfile = function(accessToken, done) { + request + .get('https://app.franceconnect.gouv.fr/api/v1/userinfo') + .query({ schema: 'openid' }) + .set('Authorization', 'Bearer ' + accessToken) + .end(function(err, result) { + if (err) return done(err); + if (!result.body || !result.body.family_name) return done(new Error('Bad content')); + done(null, result.body); + }); + }; + + passport.use('france-connect', strategy); +}; diff --git a/server/oauth/index.js b/server/oauth/index.js index b6e9948..e1977ec 100644 --- a/server/oauth/index.js +++ b/server/oauth/index.js @@ -15,9 +15,11 @@ passport.deserializeUser(function(user, done) { }); require('./local/passport').setup(User, config); +require('./france-connect/passport').setup(config); var router = express.Router(); router.use('/local', require('./local')); +router.use('/fc', require('./france-connect')); module.exports = router;