Skip to content

Implemented auth0 adapater. #7502

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: alpha
Choose a base branch
from

Conversation

lukasredev
Copy link

@lukasredev lukasredev commented Aug 19, 2021

New Pull Request Checklist

Issue Description

Implements #7478

Approach

I followed a similar approach to the apple authentication adapter.

Documentation PR: parse-community/docs#843

TODOs before merging

  • Add test cases
  • Add entry to changelog
  • Add changes to documentation (guides, repository pages, in-code descriptions)
  • Add security check
  • Add new Parse Error codes to Parse JS SDK
  • ...

Copy link
Member

@mtrezza mtrezza left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for opening this PR!

In general, I wonder why this (or any other) auth adapter is part of the Parse Server repository and not a repository of their own, like additional database adapters. That would be more in line with the modular structure of Parse Server.

try {
await auth0.validateAuthData(
{ id: 'the_user_id', id_token: 'the_token' },
{ tenantId: 'example.eu.auth0.com', clientId: 'secret' }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this a URI that is made available for development use per policy?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not, as far as I know, I just choose a value for the tests. Since the tenant is not really used in the tests, it does not really matter. Another option would be to create an auth0 account and register a tenant, but then someone from the Parse team would have to manage this account.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any benefit regarding test efficacy if we create an auth0 account? If not, I suggest we comply with RFC 2606 and replace the URLs in the tests with example.com.

@codecov
Copy link

codecov bot commented Aug 19, 2021

Codecov Report

Patch coverage: 100.00% and project coverage change: -0.43 ⚠️

Comparison is base (c9b5971) 94.37% compared to head (79e4857) 93.95%.

❗ Current head 79e4857 differs from pull request most recent head 32a9aad. Consider uploading reports for the commit 32a9aad to get more accurate results

Additional details and impacted files
@@            Coverage Diff             @@
##            alpha    #7502      +/-   ##
==========================================
- Coverage   94.37%   93.95%   -0.43%     
==========================================
  Files         185      182       -3     
  Lines       14761    13314    -1447     
==========================================
- Hits        13931    12509    -1422     
+ Misses        830      805      -25     
Impacted Files Coverage Δ
src/Adapters/Auth/auth0.js 100.00% <100.00%> (ø)
src/Adapters/Auth/index.js 93.65% <100.00%> (-4.50%) ⬇️

... and 144 files with indirect coverage changes

☔ View full report in Codecov by Sentry.
📢 Do you have feedback about the report comment? Let us know in this issue.

Copy link
Member

@dblythy dblythy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work so far! Some minor nits


it('Should throw error with missing id_token', async () => {
try {
await auth0.validateAuthData({}, { tenantId: 'example.eu.auth0.com', clientId: 'secret' });
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer

await expectAsync(auth0.validateAuthData({}, { tenantId: 'example.eu.auth0.com', clientId: 'secret' })).toBeRejectedWith(new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'id token is invalid for this user.'));

const fakeDecodedToken = { header: { kid: '123', alg: 'RS256' } };
spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken);
spyOn(jwt, 'verify').and.callFake(() => fakeClaim);
const fakeGetSigningKeyAsyncFunction = () => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could probably simplify this to:

const fakeGetSigningKeyAsyncFunction = () => ({ kid: '123', rsaPublicKey: 'the_rsa_public_key' })

// tenantId: the auth0 tenant, e.g. example.eu.auth0.com (NO HTTP / HTTPS)
// clientId: the auth0 client id, can be found in the auth0 console.

var Parse = require('parse/node').Parse;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no var

const jwt = require('jsonwebtoken');
const util = require('util');

const getAuth0KeyByKeyId = async (keyId, cacheMaxEntries, cacheMaxAge, tenantId) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some functions are arrow syntax others are regular function syntax - I would recommend consistency


let key;
try {
key = await asyncGetSigningKeyFunction(keyId);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer return await asyncGetSigningKeyFunction(keyId);, no need to define key

const { kid: keyId, alg: algorithm } = getHeaderFromToken(token);
let jwtClaims;
const ONE_HOUR_IN_MS = 3600000;
cacheMaxAge = cacheMaxAge || ONE_HOUR_IN_MS;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you use default parameters on the object destructure?

}

module.exports = {
validateAppId: validateAppId,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can use destructuring assignment here, i.e:

module.exports = {
  validateAppId,
  validateAuthData
}

@mtrezza
Copy link
Member

mtrezza commented Jul 14, 2023

@lukasreichart would you want to make the suggested changes, so we can merge this?

@am2222
Copy link

am2222 commented Nov 17, 2023

@mtrezza Is there any updates on this PR?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants