Skip to content

Commit 239767e

Browse files
Merge pull request #2 from Brightspace/develop
Develop
2 parents 8feaee8 + 45a2e95 commit 239767e

19 files changed

Lines changed: 343 additions & 242 deletions

.jshintrc

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"node": true,
3+
"bitwise": true,
4+
"camelcase": false,
5+
"curly": true,
6+
"eqeqeq": true,
7+
"immed": true,
8+
"newcap": true,
9+
"noarg": true,
10+
"quotmark": "single",
11+
"regexp": true,
12+
"undef": true,
13+
"unused": false,
14+
"strict": true,
15+
"trailing": true,
16+
"smarttabs": false,
17+
"laxcomma": true,
18+
"onevar": false,
19+
"esversion": 6
20+
}

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ Out of the box this solution was built to work with the Devcop Brightspace insta
1616
```
1717
5. Now that the required Node packages are installed the local node server can be started by running:
1818
```shell
19-
npm run start
19+
npm run local
2020
```
2121
6. The server should now be up and running locally and in a browser you can navigate to:
2222
https://localhost:3434

docs/authentication.md

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -13,25 +13,25 @@ The code for the ID/Key Authentication can be found in the [idkeyauth.js](../src
1313
```
1414
* Once the SDK is imported we can create application context using the Instance URL, the Application Key and the Application Id. The Application Key and Application Id are received when an application is registered in Brightspace using the 'Manage Extensibility' tool. The code for creating this context is:
1515
```javascript
16-
var appContext = new d2l.ApplicationContext(configs.instanceUrl, configs.applicationId, configs.applicationKey);
16+
const appContext = new d2l.ApplicationContext(configs.instanceUrl, configs.applicationId, configs.applicationKey);
1717
```
1818
* The ```/idkeyauth``` route exists in the project to initiate the ID/Key Authentication protocol using the created application context. When this route is navigated to in the browser the user is redirected to the Learning Environment where they are pompted to accept the application's ability to make APIs on their behalf. You can see in the callback that we call the [```createUserContext```](https://github.com/Brightspace/valence-sdk-javascript/blob/master/lib/valence.js#L266) which grabs userId and userKey from the query parameters returned from Brightspace.
1919
* Once they have accepted the terms the user is redirected to the ```/idkeycallback``` route where the received userKey and userId are stored in a cookie so that subsequent requests can be signed using this context. The follwing code is how the context is setup again and used:
2020
2121
```javascript
2222
// Grab the UserId and UserKey from the cookie.
23-
var userId = req.cookies[configs.cookieName].userId;
24-
var userKey = req.cookies[configs.cookieName].userKey;
23+
const userId = req.cookies[configs.cookieName].userId;
24+
const userKey = req.cookies[configs.cookieName].userKey;
2525
2626
// Setup user context using the values from the cookie.
27-
var userContext = appContext.createUserContextWithValues(configs.instanceScheme + '//' + configs.instanceUrl, configs.instancePort, userId, userKey);
27+
const userContext = appContext.createUserContextWithValues(configs.instanceScheme + '//' + configs.instanceUrl, configs.instancePort, userId, userKey);
2828

2929
// Create an authenticated URL using the SDK.
30-
var apiCallUrl = userContext.createAuthenticatedUrl(apiPath, 'GET');
30+
const apiCallUrl = userContext.createAuthenticatedUrl(apiPath, 'GET');
3131
```
3232

3333
## OAuth 2.0
34-
The code for the OAuth 2.0 implementation can be found in the [oauth.js](../src/authorization/oauth.js) file. Out of the box there are many supported OAuth 2.0 libraries that you can use in order to make your authenticated requests and support you through the authentication workflow. One thing to keep in mind is that OAuth 2.0 requires the calling application to be granted ```scopes``` that represent what routes the OAuth client can execute.
34+
The code for the OAuth 2.0 implementation can be found in the [oauth.js](../src/authorization/oauth.js) file. Out of the box there are many supported OAuth 2.0 libraries that you can use in order to make your authenticated requests and support you through the authentication workflow. One thing to keep in mind is that OAuth 2.0 requires the calling application to be granted ```scopes``` that represent what routes the OAuth client is authorized to access.
3535

3636
Currently for the samples the following scopes:
3737
* ```core:*:*```
@@ -41,9 +41,9 @@ The following is the workflow the sample has implemented:
4141
* The first order of business is to attain an authorization code from the [Authorization Endpoint](http://docs.valence.desire2learn.com/basic/oauth2.html#setting-up-oauth-2-0-authentication). In order to recieve an auth code there are several configurations that need to be sent as query parameters. The following code illustrates this:
4242
```javascript
4343
// Using the imported 'querystring' library, create the query parameter list passing in the required variables.
44-
var authCodeParams = querystring.stringify({
45-
response_type: "code",
46-
redirect_uri: configs.getRedirectUri(req),
44+
const authCodeParams = querystring.stringify({
45+
response_type: 'code',
46+
redirect_uri: helpers.getRedirectUri(req),
4747
client_id: configs.clientId,
4848
scope: configs.authCodeScope,
4949
state: configs.state
@@ -55,24 +55,24 @@ The following is the workflow the sample has implemented:
5555
* Once the user has granted the application permission the user is redirected back to the ```/oauthcallback``` route. In the callback the recieved Authorization Code is exchanged for an Access Token by calling the [Token Endpoint](http://docs.valence.desire2learn.com/basic/oauth2.html#setting-up-oauth-2-0-authentication) that can then be used to make API calls. The following code is responsible for this exchange:
5656
```javascript
5757
// Retrieve the authorization code from the query parameter.
58-
var authorizationCode = req.query.code;
58+
const authorizationCode = req.query.code;
5959
6060
// Verify that the state passed into the request for an Auth code matches the state passed back to the callback.
61-
var state = req.query.state;
61+
const state = req.query.state;
6262
if (state !== configs.state) {
63-
console.log("The state value from the authorization request was incorrect.");
64-
res.status(500).send({ error: "STATE mistmatch - authorization request could not be completed." });
63+
console.log('The state value from the authorization request was incorrect.');
64+
res.status(500).send({ error: 'STATE mistmatch - authorization request could not be completed.' });
6565
return;
6666
}
6767
6868
// Set the values that will be sent to the Token Endpoint through the body of the request.
69-
var payload = querystring.stringify({
70-
grant_type: "authorization_code",
69+
const payload = querystring.stringify({
70+
grant_type: 'authorization_code',
7171
redirect_uri: configs.getRedirectUri(req),
7272
code: authorizationCode
7373
});
7474
75-
// Using the 'superagent' library with the clientId and ClientSecret sent through the headers as Basic Authorization and the payload sent as the body.
75+
// Using the 'superagent' library with the client_id and client_secret sent through the headers as Basic Authorization and the payload sent as the body.
7676
request
7777
.post(configs.tokenEndpoint)
7878
.auth(configs.clientId, configs.clientSecret)
@@ -81,10 +81,10 @@ The following is the workflow the sample has implemented:
8181
if (err) {
8282
console.log('Access Token Error', err.response || err);
8383
res.redirect('/auth');
84-
} else if(response.statusCode != 200) {
84+
} else if(response.statusCode !== 200) {
8585
res.status(response.statusCode).send(response.error);
8686
} else {
87-
var accessToken = response.body.access_token;
87+
const accessToken = response.body.access_token;
8888
// Save the access token into a cookie to be retrieved later in order to make a request.
8989
res.cookie(configs.cookieName, { accessToken: accessToken }, configs.cookieOptions);
9090
// Redirect the user back to the index page.
@@ -95,17 +95,17 @@ The following is the workflow the sample has implemented:
9595
* Now that the Access Token has been saved in the cookie, it can be retrieved later and added as an 'Authorization' header in API requests. The following is an example of this:
9696
```javascript
9797
// Retrieve access token from the cookie.
98-
var accessToken = req.cookies[configs.cookieName].accessToken;
98+
const accessToken = req.cookies[configs.cookieName].accessToken;
9999
100100
// Set the Authorization header with the access token.
101101
request
102102
.get( whoamiRoute )
103103
.set('Authorization', `Bearer ${accessToken}`)
104104
.end(function(error, response) {
105105
if (error) {
106-
console.log("Error calling the who am I route", error);
106+
console.log('Error calling the who am I route', error);
107107
res.status(500).send({ error: error });
108-
} else if(response.statusCode != 200) {
108+
} else if(response.statusCode !== 200) {
109109
res.status(response.statusCode).send(response.error);
110110
} else {
111111
res.status(200).send(response.text);

docs/configurations.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ The [index.html]() page has several hardcoded values that indicate to the underl
4848
* ```moduleId``` can be updated to the module in content where you would like the new file to be added.
4949
* Note: if you are changing the values for the content route be sure to checkout the [content.js](../src/content.js) file in order to update the topic data block to point to the proper content location ('Url' field):
5050
```javascript
51-
var topicData = {
51+
const topicData = {
5252
Title: "Sample Word Document Content",
5353
ShortTitle: null,
5454
Type: 1,

package.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@
44
"description": "Sample application showing how to extend Brightspace using APIs, Remote Plugins and other integration points..",
55
"main": "server.js",
66
"scripts": {
7-
"test": "echo \"Error: no test specified\" && exit 1",
8-
"start": "node server-local.js"
7+
"lint": "jshint src server-local.js server.js",
8+
"local": "node server-local.js",
9+
"start": "node server.js",
10+
"test": "npm run lint"
911
},
1012
"author": "Desire2Learn Inc.",
1113
"license": "Apache License 2.0",
@@ -19,6 +21,7 @@
1921
"valence": "^1.0.3"
2022
},
2123
"devDependencies": {
24+
"jshint": "^2.9.5",
2225
"openssl-self-signed-certificate": "^1.1.6"
2326
}
2427
}

server-local.js

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
var https = require('https');
2-
var selfSigned = require('openssl-self-signed-certificate');
1+
'use strict';
32

4-
var app = require('./server');
3+
const https = require('https'),
4+
selfSigned = require('openssl-self-signed-certificate'),
5+
app = require('./server');
56

6-
var httpsPort = process.env.HTTPS_PORT || 3434;
7-
var options = {
7+
const httpsPort = process.env.HTTPS_PORT || 3434;
8+
const options = {
89
key: selfSigned.key,
910
cert: selfSigned.cert
1011
};

server.js

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
var
1+
'use strict';
2+
3+
const
24
d2l = require('valence'),
35
express = require('express'),
4-
request = require('superagent'),
56
bodyParser = require('body-parser'),
67
cookieParser = require('cookie-parser'),
78
configs = require('./src/configurations'),
@@ -12,23 +13,23 @@ app.use(bodyParser.urlencoded({ extended: true }));
1213
app.use(cookieParser());
1314

1415
// Setup the initial D2L context object using the configured instance settings.
15-
var appContext = new d2l.ApplicationContext(configs.instanceUrl, configs.applicationId, configs.applicationKey);
16+
const appContext = new d2l.ApplicationContext(configs.instanceUrl, configs.applicationId, configs.applicationKey);
1617

1718
// Import Authorization
18-
require('./src/authorization/idkeyauth.js')(app, configs, appContext);
19-
require('./src/authorization/oauth.js')(app, request, configs);
19+
app.use(require('./src/authorization/idkeyauth.js')(appContext));
20+
app.use(require('./src/authorization/oauth.js')());
2021

2122
// Import Sample API Calls
22-
require('./src/apis/whoami')(app, request, configs, appContext);
23-
require('./src/apis/content')(app, request, configs, appContext);
24-
require('./src/apis/grades')(app, request, configs, appContext);
25-
require('./src/apis/profileimage')(app, request, configs, appContext, __dirname);
23+
app.use(require('./src/apis/whoami')(appContext));
24+
app.use(require('./src/apis/content')(appContext));
25+
app.use(require('./src/apis/grades')(appContext));
26+
app.use(require('./src/apis/profileimage')(appContext, __dirname));
2627

2728
// Import Sample Remote Plugins
28-
require('./src/remote-plugins/isf-cim')(app, request, configs, appContext, path, __dirname);
29-
require('./src/remote-plugins/quicklink-cim')(app, request, configs, appContext, path, __dirname);
30-
require('./src/remote-plugins/courseimport-cim')(app, request, configs, appContext, path, __dirname);
31-
require('./src/remote-plugins/statics.js')(app, express, __dirname);
29+
app.use(require('./src/remote-plugins/isf-cim')(appContext, __dirname));
30+
app.use(require('./src/remote-plugins/quicklink-cim')(appContext,__dirname));
31+
app.use(require('./src/remote-plugins/courseimport-cim')(appContext, __dirname));
32+
require('./src/remote-plugins/statics.js')(app, __dirname);
3233

3334
/* GET /
3435
* The default server location that will return the index html page.

0 commit comments

Comments
 (0)