Skip to content

Commit

Permalink
Merge pull request #5 from sandybemonkey/ADD_UNIT_TEST
Browse files Browse the repository at this point in the history
Add the first unit test
  • Loading branch information
sandybemonkey committed Aug 7, 2018
2 parents d584fed + 8aa6ad5 commit 0844340
Show file tree
Hide file tree
Showing 24 changed files with 324 additions and 5,715 deletions.
43 changes: 21 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,7 @@

An example of Service Provider for FranceConnect.

[`doc de référence`](https://partenaires.franceconnect.gouv.fr/fournisseur-service#glossary)

`Config valide exemple` :
```json
{
"fcURL": "https://fcp.integ01.dev-franceconnect.fr",
"openIdParameters": {
"clientID": "9c771146e9ff7f45a7613ced4be01581b3abbd8e25d45fb3e45559b2577c5030",
"clientSecret": "3eb1c3fdd79669e3e4a5971ea0ac06804f27f6cbb20f29daebda95e755677ecb",
"callbackURL": "http://localhost:8000/callback",
"authorizationURL": "https://fcp.integ01.dev-franceconnect.fr/api/v1/authorize",
"tokenURL": "https://fcp.integ01.dev-franceconnect.fr/api/v1/token",
"userInfoURL": "https://fcp.integ01.dev-franceconnect.fr/api/v1/userinfo",
"logoutURL":"https://fcp.integ01.dev-franceconnect.fr/api/v1/logout",
"scope": "openid email phone given_name",
"state": "myTestServiceState",
"nonce": "timestamp123"
}
}
```
[`Documentation`](https://partenaires.franceconnect.gouv.fr/fournisseur-service#glossary)

## Install
```bash
Expand All @@ -30,7 +11,25 @@ cd service-providers-examples
npm install
```

## Run the App
## Run the app
```bash
npm start
```

## Use the app
when You start the app, the demo is available at :
```
http://localhost:3000
```
To start the France Connect Authentication process, click on the France Connect button.
You will be prompt to choose an identity provider.
When you choose your identity provider, you will be redirect to his login page.
You can you the following demo data to fill the login form.
```
login : 1234567891011
password: 123
```
## Run the Tests
```bash
npm start
npm test
```
52 changes: 40 additions & 12 deletions app.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
*/
import express from 'express';
import logger from 'morgan';
import indexRoute from './routes/index';
import logingRoute from './routes/login';
import callbackRoute from './routes/callback';
import profileRoute from './routes/profile';
import logoutRoute from './routes/logout';
import endRoute from './routes/end';

import userInfosHelper from './helpers/userInfo';
import idHintHelper from './helpers/idHintToken';
import logoutHelper from './helpers/logout';
import authorizationHelper from './helpers/authorization';
import getAccessTokenHelper from './helpers/accessToken';

const app = express();
const port = process.env.PORT || '3000';
Expand All @@ -27,12 +27,40 @@ app.use(express.static('public'));
/**
* Routes
*/
app.use('/', indexRoute);
app.use('/login', logingRoute);
app.use('/callback', callbackRoute);
app.use('/profile', profileRoute);
app.use('/logout', logoutRoute);
app.use('/end', endRoute);
app.get('/', (req, res) => {
res.render('pages/index');
});

app.get('/login', (req, res) => {
res.redirect(authorizationHelper.getAuth());
});

app.get('/callback', (req, res) => {
// check if the mandatory Authorization code is there.
if (!req.query.code) {
res.sendStatus(400);
}
getAccessTokenHelper.getAccessToken(res, req.query.code);
});

app.get('/profile', (req, res) => {
/**
* Getting the user informations by calling helpers/userInfo.
* @type {{}}
*/
const user = userInfosHelper.sendUserInfo();
res.render('pages/profile', { user });
});

app.get('/logout', (req, res) => {
res.redirect(logoutHelper.logout());
});

app.get('/end', (req, res) => {
// resetting the id token hint.
idHintHelper.resetHintToken();
res.render('pages/end');
});

const server = app.listen(port);

Expand Down
20 changes: 0 additions & 20 deletions controllers/callback.js

This file was deleted.

13 changes: 0 additions & 13 deletions controllers/end.js

This file was deleted.

8 changes: 0 additions & 8 deletions controllers/index.js

This file was deleted.

15 changes: 0 additions & 15 deletions controllers/login.js

This file was deleted.

14 changes: 0 additions & 14 deletions controllers/logout.js

This file was deleted.

26 changes: 10 additions & 16 deletions helpers/accessToken.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
* Helper to get an access token from France Connect.
* @see @link{ https://partenaires.franceconnect.gouv.fr/fcp/fournisseur-service# }
*/
import axios from "axios";
import querystring from "querystring";
import getUserHelper from "./user";
import idHintToken from "./idHintToken";
import axios from 'axios';
import querystring from 'querystring';
import getUserHelper from './user';
import idHintToken from './idHintToken';
import config from '../config/config.json';

const sendTokenToFD = false;
Expand All @@ -20,7 +20,6 @@ exports.getAccessToken = async (res, queryCode) => {
const redirectUrl = config.REDIRECT_URL;
const clientId = config.CLIENT_SECRET;
const secretKey = config.SECRET_KEY;
const userInfoUrl = config.USERINFO_URL;

// Set request params.
const url = tokenUrl;
Expand All @@ -38,12 +37,11 @@ exports.getAccessToken = async (res, queryCode) => {
};

/**
* Resquest access token.
* Request access token.
*/
await axios.post(url, querystring.stringify(body), headerConfig)
.then(response => response.data)
.then((tokenData) => {

idHintToken.setHintToken(tokenData.id_token);
/**
* Use to send the access token to an data provider.
Expand All @@ -54,23 +52,19 @@ exports.getAccessToken = async (res, queryCode) => {
if (sendTokenToFD) {
axios({
method: 'GET',
headers: {Authorization: `Bearer ${tokenData.access_token}`},
headers: { Authorization: `Bearer ${tokenData.access_token}` },
/**
* only valid used with dat-providers-example code from France Connect repo.
* If use using your code change the url's value.
* @see @link{ https://github.com/france-connect/data-providers-examples }
*/
url: 'http://localhost:4000/revenu-fiscal-de-reference',
}).catch(err => {
res.send(err.message);
});
}).catch(err => res.send(err.message));
}
/**
* Make a call to the France Connect API endpoint to get user Informations.
* Make a call to the France Connect API endpoint to get user data.
*/
getUserHelper.getUser(tokenData.access_token, res);
})
.catch(err => {
res.send(err.message);
})
}
.catch(err => res.send(err.message));
};
5 changes: 4 additions & 1 deletion helpers/idHintToken.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,7 @@ exports.getHintToken = () => idHintToken;
* Reset idHintToken after logout
* @returns {null}
*/
exports.resetHintToken = () => idHintToken = null;
exports.resetHintToken = () => {
idHintToken = null;
return idHintToken;
};
8 changes: 4 additions & 4 deletions helpers/logout.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
/**
* Init the lougout process by calling logoutHelper.logout() of helpers/logout.
* Init the logout process by calling logoutHelper.logout() of helpers/logout.
* @see @link{ https://partenaires.franceconnect.gouv.fr/fcp/fournisseur-service# }
*/
import config from '../config/config.json';
import idHintToken from '../helpers/idHintToken';
import idHintToken from './idHintToken';

/**
* Format the url 's that is used in a redirect call to France Connect logout API endpoint
* @returns {string}
*/
exports.logout = () => `${config.FC_URL}/api/v1/logout?id_token_hint=${idHintToken.getHintToken()}`
+ `&state=${config.STATE}&post_logout_redirect_uri=${config.LOGOUT_REDIRECT_URL}`;
exports.logout = () => `${config.LOGOUT_URL}?id_token_hint=${idHintToken.getHintToken()}`
+ `&state=${config.STATE}&post_logout_redirect_uri=${config.LOGOUT_REDIRECT_URL}`;
13 changes: 6 additions & 7 deletions helpers/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,23 @@
* @see @link{ https://partenaires.franceconnect.gouv.fr/fcp/fournisseur-service# }
*/

import axios from "axios";
import userInfosHelper from "./userInfo";
import axios from 'axios';
import userInfosHelper from './userInfo';
import config from '../config/config.json';

exports.getUser = async (token, res) => {
if (!token) res.sendStatus(401);
// Set request header
const headerConfig = {
headers: {
Authorization: `Bearer ${token}`,
},
};
await axios.get(config.USERINFO_URL, headerConfig)
.then(response => {
.then((response) => {
// Helper to set userInfo value available to the profile page.
userInfosHelper.getUserInfo(response.data);
res.redirect('profile');
})
.catch(err => {
res.send(err.message);
})
}
.catch(err => res.send(err.message));
};
Loading

0 comments on commit 0844340

Please sign in to comment.