Skip to content

Commit 8472252

Browse files
committed
add tests, add workflows
1 parent 9386047 commit 8472252

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

74 files changed

+1152
-297
lines changed

.github/workflows/codeql.yml

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
name: "Code Scan"
2+
3+
on:
4+
pull_request:
5+
branches:
6+
- master
7+
8+
jobs:
9+
CodeQL-Build:
10+
strategy:
11+
fail-fast: false
12+
13+
# CodeQL runs on ubuntu-latest, windows-latest, and macos-latest
14+
runs-on: ubuntu-latest
15+
16+
steps:
17+
- name: Checkout repository
18+
uses: actions/checkout@v2
19+
20+
# Initializes the CodeQL tools for scanning.
21+
- name: Initialize CodeQL
22+
uses: github/codeql-action/init@v1
23+
with:
24+
languages: javascript
25+
26+
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
27+
# If this step fails, then you should remove it and run the build manually (see below).
28+
#- name: Autobuild
29+
# uses: github/codeql-action/autobuild@v1
30+
31+
# ℹ️ Command-line programs to run using the OS shell.
32+
# 📚 https://git.io/JvXDl
33+
34+
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
35+
# and modify them (or add more) to build your code if your project
36+
# uses a compiled language
37+
38+
- name: Perform CodeQL Analysis
39+
uses: github/codeql-action/analyze@v1

.github/workflows/node.js.yml

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node
2+
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
3+
4+
name: "Build"
5+
6+
on:
7+
pull_request:
8+
branches:
9+
- master
10+
11+
jobs:
12+
build:
13+
14+
runs-on: ubuntu-latest
15+
16+
strategy:
17+
matrix:
18+
node-version: [12.x]
19+
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
20+
21+
steps:
22+
- uses: actions/checkout@v2
23+
- name: Use Node.js ${{ matrix.node-version }}
24+
uses: actions/setup-node@v2
25+
with:
26+
node-version: ${{ matrix.node-version }}
27+
28+
- run: |
29+
cd 1-Authentication/1-sign-in/
30+
npm ci
31+
npm audit --production
32+
npm run test
33+
34+
- run: |
35+
cd 1-Authentication/2-sign-in-b2c/
36+
npm ci
37+
npm audit --production
38+
npm run test
39+
40+
- run: |
41+
cd 2-Authorization-I/1-call-graph/
42+
npm ci
43+
npm audit --production
44+
npm run test
45+
46+
- run: |
47+
cd 3-Authorization-II/1-call-api/API
48+
npm ci
49+
npm audit --production
50+
npm run test
51+
52+
- run: |
53+
cd 3-Authorization-II/1-call-api/SPA
54+
npm ci
55+
npm audit --production
56+
npm run test
57+
58+
- run: |
59+
cd 3-Authorization-II/2-call-api-b2c/API
60+
npm ci
61+
npm audit --production
62+
npm run test
63+
64+
- run: |
65+
cd 3-Authorization-II/2-call-api-b2c/SPA
66+
npm ci
67+
npm audit --production
68+
npm run test
69+
70+
- run: |
71+
cd 4-AdvancedGrants/1-call-api-graph/API
72+
npm ci
73+
npm audit --production
74+
npm run test
75+
76+
- run: |
77+
cd 4-AdvancedGrants/1-call-api-graph/SPA
78+
npm ci
79+
npm audit --production
80+
npm run test
81+
82+
- run: |
83+
cd 4-AdvancedGrants/2-call-api-api-ca/DownstreamAPI
84+
npm ci
85+
npm audit --production
86+
npm run test
87+
88+
- run: |
89+
cd 4-AdvancedGrants/2-call-api-api-ca/MiddletierAPI
90+
npm ci
91+
npm audit --production
92+
npm run test
93+
94+
- run: |
95+
cd 4-AdvancedGrants/2-call-api-api-ca/SPA
96+
npm ci
97+
npm audit --production
98+
npm run test
Lines changed: 39 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,46 @@
1-
21
/**
32
* Configuration object to be passed to MSAL instance on creation.
43
* For a full list of MSAL.js configuration parameters, visit:
54
* https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/configuration.md
65
*/
76

87
const msalConfig = {
9-
auth: {
10-
clientId: "Enter_the_Application_Id_Here", // This is the ONLY mandatory field that you need to supply.
11-
authority: "Enter_the_Cloud_Instance_Id_Here/Enter_the_Tenant_Info_Here", // Defaults to "https://login.microsoftonline.com/common"
12-
redirectUri: "Enter_the_Redirect_Uri_Here", // You must register this URI on Azure Portal/App Registration. Defaults to window.location.href
13-
postLogoutRedirectUri: "Enter_the_Redirect_Uri_Here/signout", // Simply remove this line if you would like navigate to index page after logout.
14-
navigateToLoginRequestUrl: false, // If "true", will navigate back to the original request location before processing the auth code response.
15-
},
16-
cache: {
17-
cacheLocation: "localStorage", // Configures cache location. "sessionStorage" is more secure, but "localStorage" gives you SSO.
18-
storeAuthStateInCookie: false, // If you wish to store cache items in cookies as well as browser cache, set this to "true".
19-
},
20-
system: {
21-
loggerOptions: {
22-
loggerCallback: (level, message, containsPii) => {
23-
if (containsPii) {
8+
auth: {
9+
clientId: "Enter_the_Application_Id_Here", // This is the ONLY mandatory field that you need to supply.
10+
authority: "https://login.microsoftonline.com/Enter_the_Tenant_Info_Here", // Defaults to "https://login.microsoftonline.com/common"
11+
redirectUri: "Enter_the_Redirect_Uri_Here", // You must register this URI on Azure Portal/App Registration. Defaults to window.location.href
12+
postLogoutRedirectUri: "Enter_the_Redirect_Uri_Here/signout", // Simply remove this line if you would like navigate to index page after logout.
13+
navigateToLoginRequestUrl: false, // If "true", will navigate back to the original request location before processing the auth code response.
14+
},
15+
cache: {
16+
cacheLocation: "localStorage", // Configures cache location. "sessionStorage" is more secure, but "localStorage" gives you SSO.
17+
storeAuthStateInCookie: false, // If you wish to store cache items in cookies as well as browser cache, set this to "true".
18+
},
19+
system: {
20+
loggerOptions: {
21+
loggerCallback: (level, message, containsPii) => {
22+
if (containsPii) {
23+
return;
24+
}
25+
switch (level) {
26+
case msal.LogLevel.Error:
27+
console.error(message);
28+
return;
29+
case msal.LogLevel.Info:
30+
console.info(message);
31+
return;
32+
case msal.LogLevel.Verbose:
33+
console.debug(message);
34+
return;
35+
case msal.LogLevel.Warning:
36+
console.warn(message);
2437
return;
25-
}
26-
switch (level) {
27-
case msal.LogLevel.Error:
28-
console.error(message);
29-
return;
30-
case msal.LogLevel.Info:
31-
console.info(message);
32-
return;
33-
case msal.LogLevel.Verbose:
34-
console.debug(message);
35-
return;
36-
case msal.LogLevel.Warning:
37-
console.warn(message);
38-
return;
39-
}
4038
}
4139
}
4240
}
43-
};
44-
41+
}
42+
};
43+
4544
/**
4645
* Scopes you add here will be prompted for user consent during sign-in.
4746
* By default, MSAL.js will add OIDC scopes (openid, profile, email) to any login request.
@@ -61,4 +60,10 @@ const loginRequest = {
6160
// scopes: ["openid", "profile"],
6261
// loginHint: "[email protected]"
6362
// };
64-
63+
64+
// exporting config object for jest
65+
if (typeof exports !== 'undefined') {
66+
module.exports = {
67+
msalConfig: msalConfig,
68+
};
69+
}

1-Authentication/1-sign-in/App/index.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@
88
<link rel="SHORTCUT ICON" href="./favicon.svg" type="image/x-icon">
99

1010
<!-- msal.min.js can be used in the place of msal.js; included msal.js to make debug easy -->
11-
<script src="https://alcdn.msauth.net/browser/2.15.0/js/msal-browser.js"
11+
<script id="load-msal" src="https://alcdn.msauth.net/browser/2.15.0/js/msal-browser.js"
1212
integrity="sha384-dFzMiVGB5HpWZ+5w5VSif6jhWfNeplSw9ACYmQKZcY2azuT9kCxVWVI9HyfGdkHV"
1313
crossorigin="anonymous"></script>
14-
15-
<!-- To help ensure reliability, Microsoft provides a second CDN -->
14+
15+
<!-- To help ensure reliability, Microsoft provides a second CDN -->
1616
<script type="text/javascript">
1717
if (typeof Msal === 'undefined') document.write(unescape("%3Cscript src='https://alcdn.msftauth.net/browser/2.15.0/js/msal-browser.js' type='text/javascript' crossorigin='anonymous' %3E%3C/script%3E"));
1818
</script>

1-Authentication/1-sign-in/package.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
"main": "server.js",
66
"scripts": {
77
"start": "node server.js",
8-
"dev": "nodemon server.js"
8+
"dev": "nodemon server.js",
9+
"test": "jest --forceExit"
910
},
1011
"repository": {
1112
"type": "git",
@@ -32,6 +33,8 @@
3233
"morgan": "^1.10.0"
3334
},
3435
"devDependencies": {
35-
"nodemon": "^2.0.12"
36+
"jest": "^27.0.6",
37+
"nodemon": "^2.0.12",
38+
"supertest": "^6.1.4"
3639
}
3740
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/**
2+
* @jest-environment jsdom
3+
*/
4+
5+
const request = require('supertest');
6+
const path = require('path');
7+
const fs = require('fs');
8+
9+
const app = require('./server.js');
10+
11+
jest.dontMock('fs');
12+
13+
const html = fs.readFileSync(path.resolve(__dirname, './App/index.html'), 'utf8');
14+
15+
describe('Sanitize index page', () => {
16+
beforeAll(async() => {
17+
global.document.documentElement.innerHTML = html.toString();
18+
});
19+
20+
it('should have valid cdn link', () => {
21+
expect(document.getElementById("load-msal").getAttribute("src")).toContain("https://alcdn.msauth.net/browser");
22+
});
23+
});
24+
25+
describe('Sanitize configuration object', () => {
26+
beforeAll(() => {
27+
global.msalConfig = require('./App/authConfig.js').msalConfig;
28+
});
29+
30+
it('should define the config object', () => {
31+
expect(msalConfig).toBeDefined();
32+
});
33+
34+
it('should not contain credentials', () => {
35+
const regexGuid = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
36+
expect(regexGuid.test(msalConfig.auth.clientId)).toBe(false);
37+
});
38+
39+
it('should contain authority URI', () => {
40+
const regexUri = /[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)?/gi;
41+
expect(regexUri.test(msalConfig.auth.authority)).toBe(true);
42+
});
43+
});
44+
45+
describe('Ensure pages served', () => {
46+
47+
beforeAll(() => {
48+
process.env.NODE_ENV = 'test';
49+
});
50+
51+
it('should get index page', async () => {
52+
const res = await request(app)
53+
.get('/');
54+
55+
const data = await fs.promises.readFile(path.join(__dirname, './App/index.html'), 'utf8');
56+
expect(res.statusCode).toEqual(200);
57+
expect(res.text).toEqual(data);
58+
});
59+
60+
it('should get signout page', async () => {
61+
const res = await request(app)
62+
.get('/signout');
63+
64+
const data = await fs.promises.readFile(path.join(__dirname, './App/signout.html'), 'utf8');
65+
expect(res.statusCode).toEqual(200);
66+
expect(res.text).toEqual(data);
67+
});
68+
});

1-Authentication/1-sign-in/server.js

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,6 @@ const DEFAULT_PORT = process.env.PORT || 3000;
77
// initialize express.
88
const app = express();
99

10-
// Initialize variables.
11-
let port = DEFAULT_PORT;
12-
1310
// Configure morgan module to log all requests.
1411
app.use(morgan('dev'));
1512

@@ -26,6 +23,8 @@ app.get('*', (req, res) => {
2623
res.sendFile(path.join(__dirname + '/index.html'));
2724
});
2825

29-
// Start the server.
30-
app.listen(port);
31-
console.log(`Listening on port ${port}...`);
26+
app.listen(DEFAULT_PORT, () => {
27+
console.log(`Sample app listening on port ${DEFAULT_PORT}!`)
28+
});
29+
30+
module.exports = app;

1-Authentication/2-sign-in-b2c/App/authConfig.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,4 +62,11 @@ const loginRequest = {
6262
// const silentRequest = {
6363
// scopes: ["openid", "profile"],
6464
// loginHint: "[email protected]"
65-
// };
65+
// };
66+
67+
// exporting config object for jest
68+
if (typeof exports !== 'undefined') {
69+
module.exports = {
70+
msalConfig: msalConfig,
71+
};
72+
}

1-Authentication/2-sign-in-b2c/App/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
<link rel="SHORTCUT ICON" href="./favicon.svg" type="image/x-icon">
99

1010
<!-- msal.min.js can be used in the place of msal.js; included msal.js to make debug easy -->
11-
<script src="https://alcdn.msauth.net/browser/2.15.0/js/msal-browser.js"
11+
<script id="load-msal" src="https://alcdn.msauth.net/browser/2.15.0/js/msal-browser.js"
1212
integrity="sha384-dFzMiVGB5HpWZ+5w5VSif6jhWfNeplSw9ACYmQKZcY2azuT9kCxVWVI9HyfGdkHV"
1313
crossorigin="anonymous"></script>
1414

1-Authentication/2-sign-in-b2c/App/policies.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,11 @@ const b2cPolicies = {
2121
}
2222
},
2323
authorityDomain: "fabrikamb2c.b2clogin.com"
24+
}
25+
26+
// exporting config object for jest
27+
if (typeof exports !== 'undefined') {
28+
module.exports = {
29+
b2cPolicies: b2cPolicies,
30+
};
2431
}

0 commit comments

Comments
 (0)