Skip to content

Commit

Permalink
Merge branch 'master' into chore(docker)-update-to-node20
Browse files Browse the repository at this point in the history
  • Loading branch information
douglasduteil authored Mar 15, 2024
2 parents a32d66e + 1d07a2d commit 9cca070
Show file tree
Hide file tree
Showing 12 changed files with 380 additions and 221 deletions.
3 changes: 2 additions & 1 deletion .env
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ STYLESHEET_URL: https://unpkg.com/bamboo.css
CALLBACK_URL: /login-callback
MCP_CLIENT_ID: client_id
MCP_CLIENT_SECRET: client_secret
MCP_PROVIDER: https://app-test.moncomptepro.beta.gouv.fr/
MCP_PROVIDER: https://app-sandbox.moncomptepro.beta.gouv.fr/
MCP_SCOPES: "openid email profile organization"
LOGIN_HINT: ""
MCP_ID_TOKEN_SIGNED_RESPONSE_ALG: RS256
MCP_USERINFO_SIGNED_RESPONSE_ALG: ""
ACR_VALUES: ""
10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ npm start

Available env variables and there default values are listed [here](.env).

You can use the app-test.moncomptepro.beta.gouv.fr oidc provider with the following client configuration:
You can use the app-sandbox.moncomptepro.beta.gouv.fr oidc provider with the following client configuration:

```yaml
client_id: client_id
Expand All @@ -78,3 +78,11 @@ authorized_scopes: openid email profile organization
```
More clients are available at: https://github.com/betagouv/moncomptepro/blob/master/scripts/fixtures.sql
## Run Cypress test
```
cd e2e
npm i
npm test
```
1 change: 1 addition & 0 deletions e2e/.env
3 changes: 3 additions & 0 deletions e2e/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
cypress/downloads
cypress/screenshots
cypress/videos
9 changes: 6 additions & 3 deletions e2e/cypress.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { addCucumberPreprocessorPlugin } from "@badeball/cypress-cucumber-prepro
import { createEsbuildPlugin } from "@badeball/cypress-cucumber-preprocessor/esbuild";
import createBundler from "@bahmutov/cypress-esbuild-preprocessor";
import { defineConfig } from "cypress";

import "dotenv/config";
//

export default defineConfig({
Expand All @@ -14,21 +14,24 @@ export default defineConfig({
setupNodeEvents,
supportFile: false,
},
env: {
MCP_PROVIDER: process.env.MCP_PROVIDER,
},
});

//

async function setupNodeEvents(
on: Cypress.PluginEvents,
config: Cypress.PluginConfigOptions
config: Cypress.PluginConfigOptions,
) {
await addCucumberPreprocessorPlugin(on, config);

on(
"file:preprocessor",
createBundler({
plugins: [createEsbuildPlugin(config)],
})
}),
);

return config;
Expand Down
26 changes: 9 additions & 17 deletions e2e/features/connexion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,36 +23,28 @@ Then("je vois {string}", function (text: string) {
//

When("je vois {string} sur moncomptepro", (_text: string) => {
cy.origin(
"https://app-test.moncomptepro.beta.gouv.fr",
{ args: _text },
(text) => {
cy.contains(text);
}
);
cy.origin(Cypress.env("MCP_PROVIDER"), { args: _text }, (text) => {
cy.contains(text);
});
});

When("je click sur {string} sur moncomptepro", (_text: string) => {
cy.origin(
"https://app-test.moncomptepro.beta.gouv.fr",
{ args: _text },
(text) => {
cy.contains(text).click();
}
);
cy.origin(Cypress.env("MCP_PROVIDER"), { args: _text }, (text) => {
cy.contains(text).click();
});
});

When(
"je me connecte en tant que [email protected] sur moncomptepro",
(path: string) => {
cy.origin("https://app-test.moncomptepro.beta.gouv.fr", () => {
cy.origin(Cypress.env("MCP_PROVIDER"), () => {
cy.get('[name="login"]').type("[email protected]");
cy.get('[type="submit"]').click();

cy.get('[name="password"]').type("[email protected]");
cy.get('[action="/users/sign-in"] [type="submit"]')
.contains("Se connecter")
.contains("S’identifier")
.click();
});
}
},
);
41 changes: 25 additions & 16 deletions e2e/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 7 additions & 6 deletions e2e/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@
"private": true,
"type": "module",
"scripts": {
"test": "cypress run",
"start": "cd .. && npm start"
"start": "cd .. && npm start",
"test": "cypress run"
},
"devDependencies": {
"@badeball/cypress-cucumber-preprocessor": "^19.2.0",
"@badeball/cypress-cucumber-preprocessor": "^20.0.2",
"@bahmutov/cypress-esbuild-preprocessor": "^2.2.0",
"cypress": "^13.6.1",
"typescript": "^5.3.3"
}
"cypress": "^13.7.0",
"typescript": "^5.4.2"
},
"packageManager": "[email protected]+sha256.17ca6e08e7633b624e8f870db81a78f46afe119de62bcaf0a7407574139198fc"
}
37 changes: 11 additions & 26 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ app.use(
cookieSession({
name: "mcp_session",
keys: ["key1", "key2"],
})
}),
);
app.use(morgan("combined"));

Expand Down Expand Up @@ -50,15 +50,15 @@ app.get("/", async (req, res, next) => {
app.post("/login", async (req, res, next) => {
try {
const client = await getMcpClient();
const code_verifier = generators.codeVerifier();
req.session.verifier = code_verifier;
const code_challenge = generators.codeChallenge(code_verifier);
const acr_values = process.env.ACR_VALUES
? process.env.ACR_VALUES.split(",")
: null;

const redirectUrl = client.authorizationUrl({
scope: process.env.MCP_SCOPES,
code_challenge,
code_challenge_method: "S256",
login_hint: process.env.LOGIN_HINT,
// claims: { id_token: { amr: { essential: true } } },
login_hint: process.env.LOGIN_HINT || null,
acr_values,
});

res.redirect(redirectUrl);
Expand All @@ -71,9 +71,7 @@ app.get(process.env.CALLBACK_URL, async (req, res, next) => {
try {
const client = await getMcpClient();
const params = client.callbackParams(req);
const tokenSet = await client.callback(redirectUri, params, {
code_verifier: req.session.verifier,
});
const tokenSet = await client.callback(redirectUri, params);

req.session.userinfo = await client.userinfo(tokenSet.access_token);
req.session.idtoken = tokenSet.claims();
Expand All @@ -88,14 +86,10 @@ app.get(process.env.CALLBACK_URL, async (req, res, next) => {
app.post("/select-organization", async (req, res, next) => {
try {
const client = await getMcpClient();
const code_verifier = generators.codeVerifier();
req.session.verifier = code_verifier;
const code_challenge = generators.codeChallenge(code_verifier);

const redirectUrl = client.authorizationUrl({
scope: process.env.MCP_SCOPES,
code_challenge,
code_challenge_method: "S256",
login_hint: process.env.LOGIN_HINT || null,
prompt: "select_organization",
});

Expand All @@ -108,14 +102,9 @@ app.post("/select-organization", async (req, res, next) => {
app.post("/update-userinfo", async (req, res, next) => {
try {
const client = await getMcpClient();
const code_verifier = generators.codeVerifier();
req.session.verifier = code_verifier;
const code_challenge = generators.codeChallenge(code_verifier);

const redirectUrl = client.authorizationUrl({
scope: process.env.MCP_SCOPES,
code_challenge,
code_challenge_method: "S256",
login_hint: process.env.LOGIN_HINT || null,
prompt: "update_userinfo",
});

Expand All @@ -142,15 +131,11 @@ app.post("/logout", async (req, res, next) => {
app.post("/force-login", async (req, res, next) => {
try {
const client = await getMcpClient();
const code_verifier = generators.codeVerifier();
req.session.verifier = code_verifier;
const code_challenge = generators.codeChallenge(code_verifier);

const redirectUrl = client.authorizationUrl({
scope: process.env.MCP_SCOPES,
claims: { id_token: { auth_time: { essential: true } } },
code_challenge,
code_challenge_method: "S256",
login_hint: process.env.LOGIN_HINT || null,
prompt: "login",
// alternatively, you can use the 'max_age: 0'
// if so, claims parameter is not necessary as auth_time will be returned
Expand Down
Loading

0 comments on commit 9cca070

Please sign in to comment.