-
Notifications
You must be signed in to change notification settings - Fork 19
Expand file tree
/
Copy pathindex.js
More file actions
200 lines (182 loc) · 7.99 KB
/
index.js
File metadata and controls
200 lines (182 loc) · 7.99 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
/* eslint-disable */
import React, { useEffect, useState } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { Helmet } from 'react-helmet';
import MsTeamActivityLaunchScreen from 'containers/LMS/MsTeams/MsTeamActivityLaunchScreen';
import MsTeamsService from 'services/msTeams.service';
import { useLocation } from "react-router-dom";
import { Alert } from 'react-bootstrap';
import { app, authentication } from '@microsoft/teams-js';
import logo from 'assets/images/studio_new_logo_small.png';
import './style.scss';
function MsTeamsActivityContainer({ match, history }) {
const { activityId, tenantId } = match.params;
const queryParams = new URLSearchParams(useLocation().search);
const classId = queryParams.get('classId');
const assignmentId = queryParams.get('assignmentId');
const submissionId = queryParams.get('submissionId');
const view = queryParams.get('view');
const userRole = queryParams.get('userRole');
const tokenTimestamp = localStorage.getItem('msteams_token_timestamp');
const [token, setToken] = useState(localStorage.getItem('msteams_token'));
const [freshToken, setFreshToken] = useState((token && ((new Date() - new Date(tokenTimestamp)) / 1000) / 60 < 15));
const [error, setError] = useState(null);
const [activityParams, setActivityParams] = useState(null);
const [showOAuth, setShowOAuth] = useState(false);
// Getting the microsoft auth code that will allow us to request a token on the callback and redirect back here
useEffect(() => {
if (freshToken) return;
const authRequest = {
successCallback: (response) => {
MsTeamsService.msTeamsTokenObo(response).then((response) => {
localStorage.setItem('msteams_token', response.access_token);
localStorage.setItem('msteams_refresh_token', response.refresh_token);
localStorage.setItem('msteams_token_timestamp', new Date().toString());
setToken(response.access_token);
setFreshToken(true);
}).catch((e) => {
console.log('token error:', e);
// No permission grant from user or admin. Going into oauth flow
if (e.errors === 'invalid_grant') {
setShowOAuth(true);
} else {
setError('There was a problem initializing the application. Please contact your Teams administrator. E003');
}
});
},
failureCallback: (response) => {
console.log('failure:', response);
setError('There was a problem initializing the application. Please contact your Teams administrator. E002');
},
};
app.initialize().then(() => {
authentication.getAuthToken(authRequest);
}).catch(() => {
setError('There was a problem initializing the application. Please contact your Teams administrator. E001');
});
}, []);
useEffect(() => {
if (!freshToken) return;
if (!view) { // If we don't have any view info, must be in tab view
setActivityParams({
assignmentId: 'noassignment',
classId: 'noclass',
view: 'tab',
userRole: 'tabuser',
submissionId: 'preview',
mtAssignmentStatus: 'preview',
userId: 'tabuser',
});
return;
}
if (view === 'SpeedGrader') {
// Redirecting teacher to summary view
history.push(`/msteam/summary/${classId}/${activityId}/${submissionId}`);
return;
}
if (userRole === 'teacher') { // Activity viewed in preview mode by a teacher
setActivityParams({
assignmentId,
classId,
view,
userRole,
submissionId: 'preview',
mtAssignmentStatus: 'preview',
userId: 'teacher',
});
return;
}
MsTeamsService.getSubmissionStatus(token, submissionId, assignmentId, classId)
.then((response) => {
setActivityParams({
assignmentId,
classId,
view,
userRole,
submissionId,
mtAssignmentStatus: response.submission.status,
userId: response.submission.submittedBy.user.id,
});
}).catch((e) => {
console.log('Error fetching submission status', e);
setError('Error fetching submission status');
});
}, [freshToken]);
const doLogin = () => {
setShowOAuth(false);
const url = new URL(`https://login.microsoftonline.com/${tenantId}/oauth2/authorize`);
const params = new URLSearchParams();
params.append('client_id', config.teamsClientId);
params.append('response_type', 'code');
params.append('scope', 'offline_access user.read');
params.append('redirect_uri', `https://${window.location.hostname}/msteams/callback`);
params.append('state', window.location.href);
url.search = params.toString();
authentication.authenticate({ url: url.href }).then((result) => {
const tokenTimestamp = localStorage.getItem('msteams_token_timestamp');
const tempToken = localStorage.getItem('msteams_token');
setToken(tempToken);
setFreshToken((tempToken && ((new Date() - new Date(tokenTimestamp)) / 1000) / 60 < 15));
}).catch((e) => {
console.log('failed to authenticate', e);
if (e.message === 'CancelledByUser')
setError('Please reload the tab and follow the instructions in the authentication popup to use this application or ask your Teams administrator Grant consent for the Curriki Application on behalf of your organization.');
else if (e.message === 'FailedToOpenWindow')
setError('If you have a pop-up blocker, please enable pop-ups for https://teams.microsoft.com then reload the tab and follow the instructions in the authentication pop-up. Alternatively, you can ask your Teams administrator Grant consent for the Curriki Application on behalf of your organization.');
});
};
return (
<>
<div className="gclass-activity-container">
<section className="main-page-content preview iframe-height-resource-shared defaultcontainer msteams-padding">
<Helmet>
<script src={`https://${window.location.hostname}/api/storage/h5p/h5p-core/js/h5p-resizer.js`} charset="UTF-8" />
</Helmet>
<div className="flex-container previews">
<div className="activity-bg left-vdo msteams-width">
<div className="main-item-wrapper desktop-view">
<div className="item-container">
{error && (
<div className="outcome-summary-container">
<div className="loading">
<div className="loading_image">
<img src={logo} alt="Curriki Studio logo" />
</div>
<div className="loading-message">{error}</div>
</div>
</div>
)}
{showOAuth && (
<div className="outcome-summary-container">
<div className="loading">
<div className="loading_image">
<img src={logo} alt="Curriki Studio logo" />
</div>
<div className="login-message">
<p>The Curriki Studio application for Microsoft Teams requires you to grant certain permissions. Please click the login button to proceed.</p>
<button className="btn btn-primary" onClick={doLogin}>Login</button>
</div>
</div>
</div>
)}
{!error && activityParams && <MsTeamActivityLaunchScreen activityId={activityId} paramObj={activityParams} />}
</div>
</div>
</div>
</div>
</section>
</div>
</>
);
}
MsTeamsActivityContainer.defaultProps = {
};
MsTeamsActivityContainer.propTypes = {
match: PropTypes.object.isRequired,
};
const mapStateToProps = (state) => ({
});
const mapDispatchToProps = (dispatch) => ({
});
export default connect(mapStateToProps, mapDispatchToProps)(MsTeamsActivityContainer);