Skip to content

Commit 458786e

Browse files
authored
[Security] Add AAD sign out capability for sample app (#5310)
1 parent c94a3d0 commit 458786e

9 files changed

Lines changed: 136 additions & 3 deletions

File tree

.github/workflows/deploy-azure-webapps.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,12 @@ jobs:
4242
- name: Install Rush
4343
run: npm install -g @microsoft/rush@$(jq -r '.rushVersion' "rush.json")
4444

45+
- name: Inject AAD signout html for sample App
46+
run: |
47+
node ./common/scripts/inject-signout-html.mjs Calling
48+
node ./common/scripts/inject-signout-html.mjs Chat
49+
node ./common/scripts/inject-signout-html.mjs CallWithChat
50+
4551
- name: Set commit SHA as environment variable
4652
run: echo "REACT_APP_COMMIT_SHA=${GITHUB_SHA::7}" >> $GITHUB_ENV
4753

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"type": "patch",
3+
"area": "improvement",
4+
"workstream": "sample-app-aad",
5+
"comment": "Add AAD sign out capability for sample app",
6+
"packageName": "@azure/communication-react",
7+
"email": "77021369+jimchou-dev@users.noreply.github.com",
8+
"dependentChangeType": "patch"
9+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"type": "patch",
3+
"area": "improvement",
4+
"workstream": "sample-app-aad",
5+
"comment": "Add AAD sign out capability for sample app",
6+
"packageName": "@azure/communication-react",
7+
"email": "77021369+jimchou-dev@users.noreply.github.com",
8+
"dependentChangeType": "patch"
9+
}
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
#!/usr/bin/env node
2+
// Copyright (c) Microsoft Corporation.
3+
// Licensed under the MIT License.
4+
5+
import { REPO_ROOT } from './lib/index.mjs';
6+
import { readFileSync, writeFileSync } from 'fs';
7+
import path from 'path';
8+
9+
10+
const MATRIX_JSON = path.join(REPO_ROOT, 'common', 'config', 'workflows', 'matrix.json');
11+
12+
/**
13+
* This script injects sign-out html logic as part of CI pipeline.
14+
*
15+
* In uri query parameter add '&hideSignout=true' to hide the signout bar/button.
16+
*
17+
* Usage: node inject-signout-html.mjs <Calling/CallWithChat/Chat>
18+
*/
19+
function main(args) {
20+
const target = args[2]
21+
if (target !== 'Calling' && target !== 'CallWithChat' && target !== 'Chat') {
22+
throw new Error(`Usage: ${args[1]} ['Calling' | 'CallWithChat' | 'Chat']\n`);
23+
}
24+
const indexHtmlPath = path.join(REPO_ROOT, 'samples', target, 'public', 'index.html');
25+
injectSignoutToIndexHtmlFile(indexHtmlPath);
26+
}
27+
28+
function injectSignoutToIndexHtmlFile(filePath) {
29+
const bodySearchString = '<div id="root" class="Root"></div>';
30+
const headSearchString = '</head>';
31+
const styles = ` <style>
32+
.signout-bar {
33+
display: flex;
34+
background-color: #0078d4;
35+
color: white;
36+
padding: 10px;
37+
}
38+
39+
.signout-button {
40+
margin-left: auto;
41+
background-color: white;
42+
color: black;
43+
border: 1px solid;
44+
border-radius: 2px;
45+
cursor: pointer;
46+
font-size: 16px;
47+
padding: 8px 16px;
48+
transition: background-color 0.3s, color 0.3s, border-color 0.3s;
49+
}
50+
51+
.signout-button:hover {
52+
background-color: #f3f2f1;
53+
border-color: #005a9e;
54+
}
55+
56+
.signout-button:focus {
57+
outline: none;
58+
box-shadow: 0 0 0 2px rgba(0, 120, 212, 0.5);
59+
}
60+
61+
.signout-button:active {
62+
background-color: #e0e0e0;
63+
}
64+
</style>
65+
</head>`
66+
const content = `<div id="signout-container">
67+
<div id="signout-bar" class="signout-bar" style="display: flex;">
68+
<button id="signoutButton" class="signout-button">Sign Out</button>
69+
</div>
70+
</div>
71+
<div id="root" class="Root"></div>
72+
<script>
73+
// Ignore: for internal testing only
74+
function handleSignOut() {
75+
console.log("You have signed out!");
76+
window.location.href = window.location.origin + '/.auth/logout';
77+
}
78+
document.getElementById('signoutButton').addEventListener('click', handleSignOut);
79+
80+
const urlQueryParameters = new URLSearchParams(window.location.search);
81+
const display = urlQueryParameters.get('hideSignout') === 'true' ? 'none' : 'flex';
82+
document.getElementById('signout-bar').style.display = display;
83+
</script>`;
84+
try {
85+
const fileContent = readFileSync(filePath, 'utf-8');
86+
const updatedContent = fileContent
87+
.replace(new RegExp(bodySearchString, 'g'), content)
88+
.replace(new RegExp(headSearchString, 'g'), styles);
89+
writeFileSync(filePath, updatedContent, 'utf-8');
90+
console.log(`Successfully replaced "${bodySearchString}" and "${headSearchString}" with signout logic in ${filePath}`);
91+
} catch (error) {
92+
console.error('Error processing the file:', error);
93+
}
94+
}
95+
96+
main(process.argv);

samples/CallWithChat/public/index.html

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@
2121
script.src = 'https://cdn.jsdelivr.net/npm/react-render-tracker';
2222
document.head.appendChild(script);
2323
</script>
24+
<style>
25+
body { display: flex; flex-direction: column; height: auto; }
26+
#Root { flex: 1; }
27+
</style>
2428
</head>
2529

2630
<body>

samples/Calling/public/index.html

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,14 @@
2121
script.src = 'https://cdn.jsdelivr.net/npm/react-render-tracker';
2222
document.head.appendChild(script);
2323
</script>
24+
<style>
25+
body { display: flex; flex-direction: column; height: auto; }
26+
#Root { flex: 1; }
27+
</style>
2428
</head>
2529

2630
<body>
27-
<main id="root" class="Root"></main>
31+
<div id="root" class="Root"></div>
2832
<script type="text/javascript">
2933
window.FabricConfig = {};
3034
</script>

samples/Chat/public/index.html

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,12 @@
2222
script.src = 'https://cdn.jsdelivr.net/npm/react-render-tracker';
2323
document.head.appendChild(script);
2424
</script>
25+
<style>
26+
body { display: flex; flex-direction: column; height: auto; }
27+
#Root { flex: 1; }
28+
</style>
2529
</head>
30+
2631
<body>
2732
<div id="root" class="Root"></div>
2833
<script type="text/javascript">

samples/Chat/src/app/ChatHeader.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ export interface ChatHeaderProps extends PeopleButtonProps {
3030
export const ChatHeader = (props: ChatHeaderProps): JSX.Element => {
3131
const theme = useTheme();
3232

33-
const leaveString = 'Leave';
33+
const leaveString = 'Leave Chat';
3434
return (
3535
<Stack
3636
horizontal={true}

samples/Chat/src/app/styles/ChatHeader.styles.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export const chatHeaderContainerStyle = mergeStyles({
1515

1616
export const leaveButtonStyle = mergeStyles({
1717
marginRight: '0.625rem',
18-
width: '6.688rem',
18+
width: '8rem',
1919
borderWidth: '0.125rem',
2020
fontSize: '0.875rem', // 14px
2121
fontWeight: 600

0 commit comments

Comments
 (0)