Skip to content

Commit 63417e2

Browse files
Refactor test (move to mocha, add login/logout coverage), add nyc, travis
1 parent d43a9ac commit 63417e2

7 files changed

Lines changed: 320 additions & 237 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,4 @@ lib
3737
dist
3838
demo/solid-client.min.js*
3939

40+
.nyc_output

.travis.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
sudo: false
2+
language: node_js
3+
node_js:
4+
- ">=7.0"
5+
6+
cache:
7+
directories:
8+
- node_modules

README.md

Lines changed: 70 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,22 +12,84 @@ It is meant to be used in browser-side applications, as part of `solid-client`.
1212

1313
### Usage
1414

15+
##### currentUser
16+
17+
`Promise<string|null> currentUser()`
18+
19+
Resolves to the WebID URI of the currently authenticated user, or `null` if none
20+
found.
21+
22+
This SHOULD be checked either on page load or on whatever "Application is
23+
ready" event that your framework provides. For example:
24+
1525
```js
1626
// Using a standard "document loaded" event listener
1727
// (equivalent to jQuery's $(document).ready())
18-
// Trigger a login() check on page load, in case user is logged in already
1928
document.addEventListener('DOMContentLoaded', function () {
20-
SolidClient.auth.login()
29+
solidClient.currentUser()
2130
.then(function (webId) {
22-
// User is logged in, you can display their webId, load their profile, etc
23-
// Solid.auth.webId is set to the current user's webId URI
24-
// Also, SolidClient.auth.accessToken is set to the current user's access token
31+
if (webId) {
32+
// User is logged in, you can display their webId, load their profile, etc
33+
} else {
34+
// Not logged in, display appropriate Login button / UI
35+
}
2536
})
2637
.catch(function (error) {
27-
// An error has occurred while logging in, display it to user
38+
// An error has occurred, display it to user
2839
})
2940
})
3041
```
3142

32-
Called by itself, `login()` will perform Provider Discovery and kick off the
33-
OAuth2/OpenID Connect `/authorize` process.
43+
##### login
44+
45+
`Promise<string|null> login([string providerUri])`
46+
47+
This is the main "authenticate to your favorite server/identity provider"
48+
action, which can be hooked up to whatever 'Login' button or link that your
49+
UI provides.
50+
51+
App developers will use it in one of two ways:
52+
53+
a) (typical) Your app does not provide its own Select Provider UI, so you can
54+
just call `.login()` by itself with no parameter, which uses the built-in
55+
provider selection UI.
56+
b) Your app *does* provide its own Select Provider UI. In this case, you can
57+
perform provider selection and pass in the `providerUri` to `.login()`
58+
directly.
59+
60+
Called by itself (without a `providerUri`), `login()` does the following:
61+
62+
1. If the user has already logged in, it resolves with their WebID URI
63+
2. Otherwise, opens a 'Select Provider' popup window, asking the user to select
64+
their identity provider (Solid server, pod, etc) to login to.
65+
3. The user makes their selection, and the popup closes and the current page
66+
is redirected to that provider's `/authorize` endpoint
67+
4. When the user has gone through the local login process etc, they are
68+
redirected back to the current page (from which `login()` was invoked)
69+
70+
If `login()` is called *with* a `providerUri` argument, the Select Provider
71+
popup window step is skipped, and the user proceeds directly to the auth
72+
workflow.
73+
74+
```js
75+
// You can bind any sort of Login button or link to do the following:
76+
solidClient.login()
77+
.then(function (webId) {
78+
// User is logged in, you can display their webId, load their profile, etc
79+
})
80+
.catch(function (error) {
81+
// An error has occurred while logging in, display it to user
82+
})
83+
```
84+
85+
After `login()` is successful, the following variables are set:
86+
87+
- `solidClient.auth.webId` is set to the current user's webId URI
88+
- `solidClient.auth.accessToken` is set to the current user's access token
89+
90+
##### selectProvider
91+
92+
`Promise<string> selectProvider ([string providerUri])`
93+
94+
##### logout
95+

karma.conf.js

Lines changed: 0 additions & 50 deletions
This file was deleted.

package.json

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "solid-auth-oidc",
33
"version": "0.0.4",
44
"engines": {
5-
"node": "^6.0"
5+
"node": ">= 7.0"
66
},
77
"description": "Authentication library for Solid client based on OAuth2/OpenID Connect",
88
"main": "./lib/index.js",
@@ -15,13 +15,19 @@
1515
"build-dist": "webpack --progress --colors --optimize-occurrence-order --optimize-dedupe --optimize-minimize",
1616
"build-lib": "babel src -d lib",
1717
"dist": "npm run build && npm run build-dist",
18-
"karma": "./node_modules/.bin/karma start",
18+
"mocha": "nyc mocha test/*.js",
1919
"postversion": "git push --follow-tags",
2020
"prepublish": "npm run build && npm run test",
2121
"preversion": "npm test",
2222
"standard": "standard src/*",
23-
"tape": "tape test/unit/*.js",
24-
"test": "npm run standard && npm run dist && npm run karma"
23+
"test": "npm run standard && npm run mocha"
24+
},
25+
"nyc": {
26+
"reporter": [
27+
"html",
28+
"text-summary"
29+
],
30+
"cache": true
2531
},
2632
"repository": {
2733
"type": "git",
@@ -57,15 +63,13 @@
5763
"babel-core": "^6.21.0",
5864
"babel-loader": "^6.2.5",
5965
"babel-preset-es2015": "^6.18.0",
60-
"karma": "^1.3.0",
61-
"karma-babel-preprocessor": "^6.0.1",
62-
"karma-chrome-launcher": "^2.0.0",
63-
"karma-mocha": "^1.3.0",
64-
"karma-sinon-chai": "^1.2.4",
65-
"karma-webpack": "^2.0.3",
66+
"chai": "^3.5.0",
67+
"chai-as-promised": "^6.0.0",
68+
"localstorage-polyfill": "^1.0.1",
6669
"mocha": "^3.2.0",
67-
"sinon": "^1.17.7",
68-
"sinon-chai": "^2.8.0",
70+
"nyc": "^10.2.0",
71+
"sinon": "^2.1.0",
72+
"sinon-chai": "^2.9.0",
6973
"standard": "^9.0.2",
7074
"webpack": "^1.14.0"
7175
},

src/index.js

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ class ClientAuthOIDC {
4545
constructor (options = {}) {
4646
this.window = options.window || global.window
4747
this.localStorage = options.localStorage || global.localStorage
48+
4849
this.currentClient = null
4950
this.providerUri = null
5051
this.webId = null
@@ -73,8 +74,10 @@ class ClientAuthOIDC {
7374
if (this.webId) {
7475
return Promise.resolve(this.webId)
7576
}
77+
7678
// Attempt to find a provider based on the 'state' param of the current URI
7779
let providerUri = this.providerFromCurrentUri()
80+
7881
if (providerUri) {
7982
return this.login(providerUri)
8083
} else {
@@ -92,18 +95,21 @@ class ClientAuthOIDC {
9295
if (!uri) { return null }
9396
let uriObj = new URL(uri)
9497
let state
98+
9599
if (uriType === HASH) {
96100
let hash = uriObj.hash || '#'
97101
let params = new URLSearchParams(hash.substr(1))
98102
state = params.get('state')
99103
}
104+
100105
if (uriType === QUERY) {
101106
state = uriObj.searchParams.get('state')
102107
}
108+
103109
return state
104110
}
105111

106-
keyByProvider (providerUri = this.providerUri) {
112+
keyByProvider (providerUri) {
107113
return `oidc.rp.by-provider.${providerUri}`
108114
}
109115

@@ -120,6 +126,7 @@ class ClientAuthOIDC {
120126
*/
121127
loadOrRegisterClient (providerUri) {
122128
this.currentClient = null
129+
123130
return this.loadClient(providerUri)
124131
.then(loadedClient => {
125132
if (loadedClient) {
@@ -149,6 +156,7 @@ class ClientAuthOIDC {
149156
// Check for client config stored locally
150157
let key = this.keyByProvider(providerUri)
151158
let clientConfig = localStorage.getItem(key)
159+
152160
if (clientConfig) {
153161
clientConfig = JSON.parse(clientConfig)
154162
return RelyingParty.from(clientConfig)
@@ -169,10 +177,9 @@ class ClientAuthOIDC {
169177
}
170178

171179
/**
172-
* Resolves to the WebID URI of the current user. Intended to be called
173-
* on page load (in case the user is already authenticated), as well as
174-
* triggered when the user initiates login explicitly (such as by pressing
175-
* a Login button, etc).
180+
* Resolves to the WebID URI of the current user. Intended to be triggered
181+
* when the user initiates login explicitly (such as by pressing a Login
182+
* button, etc).
176183
*
177184
* @param [providerUri] {string} Provider URI, result of a Provider Selection
178185
* operation (that the app developer has provided). If `null`, the
@@ -182,10 +189,9 @@ class ClientAuthOIDC {
182189
*/
183190
login (providerUri) {
184191
this.clearCurrentUser()
185-
let selectProvider = this.selectProvider.bind(this)
186192

187193
return Promise.resolve(providerUri)
188-
.then(selectProvider)
194+
.then(providerUri => this.selectProvider(providerUri))
189195
.then(selectedProviderUri => {
190196
if (selectedProviderUri) {
191197
return this.loadOrRegisterClient(selectedProviderUri)
@@ -206,9 +212,9 @@ class ClientAuthOIDC {
206212

207213
logout () {
208214
this.clearCurrentUser()
209-
if (!this.currentClient) {
210-
return Promise.resolve(null)
211-
}
215+
216+
if (!this.currentClient) { return Promise.resolve(null) }
217+
212218
return this.currentClient.logout()
213219
}
214220

@@ -232,11 +238,13 @@ class ClientAuthOIDC {
232238
if (providerUri) {
233239
return Promise.resolve(providerUri)
234240
}
241+
235242
// Attempt to find a provider based on the 'state' param of the current URI
236243
providerUri = this.providerFromCurrentUri()
237244
if (providerUri) {
238245
return Promise.resolve(providerUri)
239246
}
247+
240248
// Lastly, kick off a Select Provider popup window workflow
241249
return this.providerFromUI()
242250
}
@@ -251,6 +259,7 @@ class ClientAuthOIDC {
251259
providerFromCurrentUri () {
252260
let currentUri = this.currentLocation()
253261
let stateParam = this.extractState(currentUri, HASH)
262+
254263
if (stateParam) {
255264
return this.loadProvider(stateParam)
256265
} else {
@@ -285,6 +294,7 @@ class ClientAuthOIDC {
285294
currentUriHasAuthResponse () {
286295
let currentUri = this.currentLocation()
287296
let stateParam = this.extractState(currentUri, HASH)
297+
288298
return !!stateParam
289299
}
290300

@@ -294,6 +304,7 @@ class ClientAuthOIDC {
294304
*/
295305
redirectTo (uri) {
296306
this.window.location.href = uri
307+
297308
return false
298309
}
299310

@@ -306,6 +317,7 @@ class ClientAuthOIDC {
306317
sendAuthRequest (client) {
307318
let options = {}
308319
let providerUri = client.provider.url
320+
309321
return client.createRequest(options, this.localStorage)
310322
.then(authUri => {
311323
let state = this.extractState(authUri, QUERY)

0 commit comments

Comments
 (0)