Skip to content

Commit 175750c

Browse files
author
Sachin Maheshwari
committed
initial ver
1 parent 41274f3 commit 175750c

File tree

6 files changed

+235
-0
lines changed

6 files changed

+235
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
node_modules
2+
package-lock.json

index.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
const { configureConnector, getFreshToken } = require ('./src/connector-wrapper')
2+
const { isTokenExpired, decodeToken } = require('./src/token')
3+
4+
module.exports = {
5+
configureConnector,
6+
getFreshToken,
7+
isTokenExpired,
8+
decodeToken
9+
}

package.json

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"name": "tc-auth-lib",
3+
"version": "1.0.0",
4+
"description": "Topcoder Authentication lib ",
5+
"main": "index.js",
6+
"scripts": {
7+
"test": "echo \"Error: no test specified\" && exit 1"
8+
},
9+
"repository": {
10+
"type": "git",
11+
"url": "git+https://github.com/topcoder-platform/authlib.git"
12+
},
13+
"keywords": [
14+
"topcoder",
15+
"authentication"
16+
],
17+
"author": "Topcoder Team",
18+
"license": "ISC",
19+
"bugs": {
20+
"url": "https://github.com/topcoder-platform/authlib/issues"
21+
},
22+
"homepage": "https://github.com/topcoder-platform/authlib#readme",
23+
"dependencies": {
24+
"lodash": "^4.17.19"
25+
}
26+
}

src/connector-wrapper.js

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
const {createFrame} = require('./iframe')
2+
const {getToken} = require ('./token')
3+
4+
let iframe = null
5+
let loading = null
6+
let url = ''
7+
let mock = false
8+
let token = ''
9+
10+
function configureConnector({connectorUrl, frameId, mockMode, mockToken}) {
11+
if (mockMode) {
12+
mock = true
13+
token = mockToken
14+
} else if (iframe) {
15+
console.warn('tc-accounts connector can only be configured once, this request has been ignored.')
16+
} else {
17+
iframe = createFrame(frameId, connectorUrl)
18+
url = connectorUrl
19+
20+
loading = new Promise( (resolve) => {
21+
iframe.onload = function() {
22+
loading = null
23+
resolve()
24+
}
25+
})
26+
}
27+
}
28+
29+
const proxyCall = function() {
30+
if (mock) {
31+
throw new Error('connector is running in mock mode. This method (proxyCall) should not be invoked.')
32+
}
33+
34+
if (!iframe) {
35+
throw new Error('connector has not yet been configured.')
36+
}
37+
38+
function request() {
39+
/*return new Promise( (resolve, reject) => {
40+
function receiveMessage(e) {
41+
const safeFormat = e.data.type === SUCCESS || e.data.type === FAILURE
42+
if (safeFormat) {
43+
window.removeEventListener('message', receiveMessage)
44+
if (e.data.type === SUCCESS) resolve(e.data)
45+
if (e.data.type === FAILURE) reject(e.error)
46+
}
47+
}
48+
49+
window.addEventListener('message', receiveMessage)
50+
51+
const payload = Object.assign({}, { type: REQUEST }, params)
52+
53+
iframe.contentWindow.postMessage(payload, url)
54+
}) */
55+
return new Promise((resolve, reject) => {
56+
const token = getToken('tcjwt')
57+
token ? resolve({ token: token }) : reject("tcjwt cookie not found")
58+
})
59+
}
60+
61+
if (loading) {
62+
return loading = loading.then(request)
63+
} else {
64+
return request()
65+
}
66+
}
67+
68+
function getFreshToken() {
69+
if (mock) {
70+
if (token) {
71+
return Promise.resolve(token)
72+
} else {
73+
return Promise.reject('connector is running in mock mode, but no token has been specified.')
74+
}
75+
}
76+
77+
return proxyCall()
78+
.then( data => data.token )
79+
}
80+
81+
module.exports = {
82+
getFreshToken,
83+
configureConnector
84+
}
85+

src/iframe.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
function createFrame(id, src) {
2+
const iframe = document.createElement('iframe')
3+
4+
iframe.id = id
5+
iframe.src = src
6+
iframe.width = 0
7+
iframe.height = 0
8+
iframe.frameborder = 0
9+
10+
document.body.appendChild(iframe)
11+
12+
return iframe
13+
}
14+
module.exports = {
15+
createFrame
16+
}

src/token.js

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
const fromPairs = require('lodash/fromPairs')
2+
3+
4+
function getToken(key) {
5+
return readCookie(key)
6+
}
7+
8+
9+
function decodeToken(token) {
10+
const parts = token.split('.')
11+
12+
if (parts.length !== 3) {
13+
throw new Error('The token is invalid')
14+
}
15+
16+
const decoded = urlBase64Decode(parts[1])
17+
18+
if (!decoded) {
19+
throw new Error('Cannot decode the token')
20+
}
21+
22+
// covert base64 token in JSON object
23+
let t = JSON.parse(decoded)
24+
25+
// tweaking for custom claim for RS256
26+
t.userId = _.parseInt(_.find(t, (value, key) => {
27+
return (key.indexOf('userId') !== -1)
28+
}))
29+
t.handle = _.find(t, (value, key) => {
30+
return (key.indexOf('handle') !== -1)
31+
})
32+
t.roles = _.find(t, (value, key) => {
33+
return (key.indexOf('roles') !== -1)
34+
})
35+
36+
return t
37+
}
38+
39+
function isTokenExpired(token, offsetSeconds = 0) {
40+
const d = getTokenExpirationDate(token)
41+
42+
if (d === null) {
43+
return false
44+
}
45+
46+
// Token expired?
47+
return !(d.valueOf() > (new Date().valueOf() + (offsetSeconds * 1000)))
48+
}
49+
50+
function urlBase64Decode(str) {
51+
let output = str.replace(/-/g, '+').replace(/_/g, '/')
52+
53+
switch (output.length % 4) {
54+
case 0:
55+
break
56+
57+
case 2:
58+
output += '=='
59+
break
60+
61+
case 3:
62+
output += '='
63+
break
64+
65+
default:
66+
throw 'Illegal base64url string!'
67+
}
68+
return decodeURIComponent(escape(atob(output))) //polyfill https://github.com/davidchambers/Base64.js
69+
}
70+
71+
function getTokenExpirationDate(token) {
72+
const decoded = decodeToken(token)
73+
74+
if (typeof decoded.exp === 'undefined') {
75+
return null
76+
}
77+
78+
const d = new Date(0) // The 0 here is the key, which sets the date to the epoch
79+
d.setUTCSeconds(decoded.exp)
80+
81+
return d
82+
}
83+
84+
function parseCookie(cookie) {
85+
return fromPairs(cookie.split(';').map((pair) => pair.split('=').map((part) => part.trim())))
86+
}
87+
88+
function readCookie(name) {
89+
return parseCookie(document.cookie)[name]
90+
}
91+
92+
93+
module.exports = {
94+
isTokenExpired,
95+
decodeToken,
96+
getToken
97+
}

0 commit comments

Comments
 (0)