Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #23 from williamchong007/develop
Add user profile and civic liker oauth api
- Loading branch information
Showing
25 changed files
with
265 additions
and
80 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
import { setNoCacheHeader } from './noCache'; | ||
import { | ||
getProviderJWTSecret, | ||
publicKey as verifySecret, | ||
defaultAudience, | ||
getToken, | ||
issuer, | ||
} from '../util/jwt'; | ||
import { | ||
oAuthClientCollection as oAuthClientDbRef, | ||
} from '../util/firebase'; | ||
|
||
const expressjwt = require('express-jwt'); | ||
const jwt = require('jsonwebtoken'); | ||
|
||
async function fetchProviderClientSecret(clientId) { | ||
const spClient = await oAuthClientDbRef.doc(clientId).get(); | ||
if (!spClient.exists) throw new Error('INVALID_AZP'); | ||
const { | ||
secret, | ||
} = spClient.data(); | ||
return secret; | ||
} | ||
|
||
function checkPermissions(inputScopes, target) { | ||
let scopes = inputScopes; | ||
if (!scopes) return false; | ||
if (!Array.isArray(scopes)) scopes = scopes.split(' '); | ||
let targets = target.split(':'); | ||
if (targets.length > 1) { | ||
const permission = targets[0]; | ||
const subScopes = targets[1].split('.'); | ||
let lastScope = `${permission}:${subScopes[0]}`; | ||
const list = [permission, lastScope]; | ||
for (let i = 1; i < subScopes.length; i += 1) { | ||
const currentScope = `${lastScope}.${subScopes[i]}`; | ||
list.push(currentScope); | ||
lastScope = currentScope; | ||
} | ||
targets = list; | ||
} | ||
if (scopes.find(scope => targets.includes(scope))) return true; | ||
return false; | ||
} | ||
|
||
export const jwtAuth = ( | ||
permission = 'read', | ||
secret = verifySecret, | ||
{ audience = defaultAudience } = {}, | ||
) => async (req, res, next) => { | ||
setNoCacheHeader(res); | ||
try { | ||
const token = getToken(req); | ||
const decoded = jwt.decode(token); | ||
if (decoded.azp) { | ||
const clientSecret = await fetchProviderClientSecret(decoded.azp); | ||
secret = getProviderJWTSecret(clientSecret); // eslint-disable-line no-param-reassign | ||
} | ||
} catch (err) { | ||
// no op | ||
} | ||
expressjwt({ | ||
secret, | ||
getToken, | ||
audience, | ||
issuer, | ||
})(req, res, (e) => { | ||
if (e instanceof expressjwt.UnauthorizedError) { | ||
res.status(401).send('LOGIN_NEEDED'); | ||
return; | ||
} | ||
if (!req.user | ||
|| (permission && !req.user.permissions && !req.user.scope) | ||
|| ((permission && !checkPermissions(req.user.permissions, permission)) | ||
&& (permission && !checkPermissions(req.user.scope, permission)))) { | ||
res.status(401).send('INVALID_GRANT'); | ||
return; | ||
} | ||
next(e); | ||
}); | ||
}; | ||
|
||
export const jwtOptionalAuth = ( | ||
permission = 'read', | ||
secret = verifySecret, | ||
{ audience = defaultAudience } = {}, | ||
) => async (req, res, next) => { | ||
setNoCacheHeader(res); | ||
try { | ||
const token = getToken(req); | ||
const decoded = jwt.decode(token); | ||
if (decoded.azp) { | ||
const clientSecret = await fetchProviderClientSecret(decoded.azp); | ||
secret = getProviderJWTSecret(clientSecret); // eslint-disable-line no-param-reassign | ||
} | ||
} catch (err) { | ||
// no op | ||
} | ||
expressjwt({ | ||
credentialsRequired: false, | ||
secret, | ||
getToken, | ||
audience, | ||
issuer, | ||
})(req, res, (e) => { | ||
if (e instanceof expressjwt.UnauthorizedError) { | ||
next(); | ||
return; | ||
} | ||
if (!req.user | ||
|| (permission && !req.user.permissions && !req.user.scope) | ||
|| ((permission && !checkPermissions(req.user.permissions, permission)) | ||
&& (permission && !checkPermissions(req.user.scope, permission)))) { | ||
req.user = undefined; | ||
} | ||
next(e); | ||
}); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
export function setNoCacheHeader(res) { | ||
res.setHeader('Surrogate-Control', 'no-store'); | ||
res.setHeader( | ||
'Cache-Control', | ||
'no-store, no-cache, must-revalidate, proxy-revalidate', | ||
); | ||
res.setHeader('Pragma', 'no-cache'); | ||
res.setHeader('Expires', '0'); | ||
} | ||
|
||
export default setNoCacheHeader; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import { Router } from 'express'; | ||
import { jwtAuth } from '../../middleware/jwt'; | ||
import { | ||
filterUserDataScoped, | ||
} from '../../util/ValidationHelper'; | ||
import { | ||
getUserWithCivicLikerProperties, | ||
} from '../../util/api/users/getPublicInfo'; | ||
|
||
const router = Router(); | ||
|
||
router.get('/profile', jwtAuth('profile'), async (req, res, next) => { | ||
try { | ||
const username = req.user.user; | ||
const payload = await getUserWithCivicLikerProperties(username); | ||
if (payload) { | ||
res.json(filterUserDataScoped(payload, req.user.scope)); | ||
} else { | ||
res.sendStatus(404); | ||
} | ||
} catch (err) { | ||
next(err); | ||
} | ||
}); | ||
|
||
export default router; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.