trusted-accounts-sdk-node
Advanced tools
Comparing version 1.0.8 to 1.0.9
118
index.js
@@ -1,90 +0,74 @@ | ||
import axios from 'axios'; | ||
import qs from 'querystring'; // For encoding the data for POST requests | ||
import { Issuer, generators } from 'openid-client'; | ||
class TrustedAccountsClient { | ||
constructor( | ||
clientId, | ||
clientSecret, | ||
redirectUri, | ||
authUrl = 'https://auth.trustedaccounts.org/oauth2/auth', | ||
tokenUrl = 'https://auth.trustedaccounts.org/oauth2/token' | ||
) { | ||
constructor(clientId, clientSecret, redirectUri, issuerUrl = 'https://auth.trustedaccounts.org/oauth2') { | ||
this.clientId = clientId; | ||
this.clientSecret = clientSecret; | ||
this.redirectUri = redirectUri; | ||
this.authUrl = authUrl; | ||
this.tokenUrl = tokenUrl; | ||
this.issuerUrl = issuerUrl; | ||
this.client = null; // This will be set after discovery | ||
} | ||
// Generate the authorization URL (for the user to authenticate) | ||
// Initialize the OpenID Client | ||
async initialize() { | ||
try { | ||
const issuer = await Issuer.discover(this.issuerUrl); // Discover the issuer based on the provided URL | ||
this.client = new issuer.Client({ | ||
client_id: this.clientId, | ||
client_secret: this.clientSecret, | ||
redirect_uris: [this.redirectUri], | ||
response_types: ['code'], | ||
}); | ||
} catch (error) { | ||
console.error('Error during issuer discovery:', error); | ||
throw new Error('Issuer discovery failed'); | ||
} | ||
} | ||
// Generate the authorization URL (for user authentication) | ||
generateVerificationLink(email) { | ||
const state = Math.random().toString(36).substring(2); // Generate a random state value | ||
const nonce = Math.random().toString(36).substring(2); // Generate a random nonce value | ||
if (!this.client) { | ||
throw new Error('Client is not initialized'); | ||
} | ||
const url = new URL(this.authUrl); | ||
url.searchParams.append('client_id', this.clientId); | ||
url.searchParams.append('redirect_uri', this.redirectUri); | ||
url.searchParams.append('response_type', 'code'); // Using Authorization Code Flow | ||
url.searchParams.append('scope', 'openid'); | ||
url.searchParams.append('state', state); | ||
url.searchParams.append('email', email); // Optionally pass user-specific details | ||
url.searchParams.append('nonce', nonce); // Generate a random nonce | ||
const state = generators.state(); // Generates a random state | ||
const nonce = generators.nonce(); // Generates a random nonce | ||
return url.toString(); | ||
// Build the URL with necessary parameters | ||
return this.client.authorizationUrl({ | ||
scope: 'openid', | ||
state: state, | ||
nonce: nonce, | ||
email: email, // Optionally, pass user-specific details | ||
}); | ||
} | ||
// Handle the callback after the user completes the verification | ||
async handleCallback(url) { | ||
const urlParams = new URLSearchParams(new URL(url).search); // Extract search parameters from URL | ||
const authorizationCode = urlParams.get('code'); | ||
const state = urlParams.get('state'); | ||
if (!authorizationCode) { | ||
throw new Error('Authorization code missing in callback URL'); | ||
async handleCallback(code, state) { | ||
if (!code || !state) { | ||
throw new Error('Missing authorization code or state in callback'); | ||
} | ||
if (!state) { | ||
throw new Error('State parameter missing in callback URL'); | ||
// Exchange the authorization code for tokens | ||
try { | ||
const tokenSet = await this.client.callback(this.redirectUri, { code, state }); | ||
return tokenSet; // Returns the token set containing access_token, id_token, etc. | ||
} catch (error) { | ||
console.error('Error during callback processing:', error); | ||
throw new Error('Failed to handle callback'); | ||
} | ||
// Exchange the authorization code for an access token | ||
const tokenResponse = await this.exchangeCodeForToken(authorizationCode, state); | ||
// Decode the ID Token (or use access token to access the user data) | ||
const trustedId = this.decodeIdToken(tokenResponse.id_token); | ||
return trustedId; | ||
} | ||
// Exchange the authorization code for an access token | ||
async exchangeCodeForToken(code, state) { | ||
const tokenData = { | ||
client_id: this.clientId, | ||
client_secret: this.clientSecret, | ||
code: code, | ||
redirect_uri: this.redirectUri, | ||
grant_type: 'authorization_code', | ||
}; | ||
const response = await axios.post(this.tokenUrl, qs.stringify(tokenData), { | ||
headers: { | ||
'Content-Type': 'application/x-www-form-urlencoded', | ||
}, | ||
}); | ||
// Return the token response which includes id_token and access_token | ||
return response.data; | ||
} | ||
// Decode the ID Token and return the "sub" (user's unique Trusted ID) | ||
// Decode the ID Token and return the user's unique Trusted ID ("sub") | ||
decodeIdToken(idToken) { | ||
const base64Url = idToken.split('.')[1]; // Get the payload part of the JWT | ||
const base64 = base64Url.replace('-', '+').replace('_', '/'); // Base64URL decode | ||
const jsonPayload = Buffer.from(base64, 'base64').toString('utf8'); | ||
const decodedPayload = JSON.parse(jsonPayload); | ||
if (!idToken) { | ||
throw new Error('ID Token is missing'); | ||
} | ||
// Return the "sub" (user's unique Trusted ID) | ||
return decodedPayload.sub; | ||
// Decode the ID Token using openid-client's built-in functionality | ||
const parsedToken = this.client.decode(idToken); | ||
return parsedToken.sub; // The "sub" claim represents the user's unique ID | ||
} | ||
} | ||
export default TrustedAccountsClient; | ||
export default TrustedAccountsClient; |
{ | ||
"name": "trusted-accounts-sdk-node", | ||
"type": "module", | ||
"version": "1.0.8", | ||
"version": "1.0.9", | ||
"description": "A simple SDK for Trusted Accounts for NodeJS", | ||
@@ -24,5 +24,4 @@ "main": "index.js", | ||
"dependencies": { | ||
"axios": "^1.7.7", | ||
"querystring": "^0.2.1" | ||
"openid-client": "^6.1.3" | ||
} | ||
} |
@@ -7,3 +7,3 @@ // trusted-accounts-sdk-node.d.ts | ||
generateVerificationLink(email: string): Promise<string>; | ||
handleCallback(callbackUrl: string): Promise<string>; | ||
handleCallback(code: string, state: string): Promise<string>; | ||
} | ||
@@ -10,0 +10,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1
5250
72
+ Addedopenid-client@^6.1.3
+ Addedjose@5.9.6(transitive)
+ Addedoauth4webapi@3.1.3(transitive)
+ Addedopenid-client@6.1.4(transitive)
- Removedaxios@^1.7.7
- Removedquerystring@^0.2.1
- Removedasynckit@0.4.0(transitive)
- Removedaxios@1.7.7(transitive)
- Removedcombined-stream@1.0.8(transitive)
- Removeddelayed-stream@1.0.0(transitive)
- Removedfollow-redirects@1.15.9(transitive)
- Removedform-data@4.0.1(transitive)
- Removedmime-db@1.52.0(transitive)
- Removedmime-types@2.1.35(transitive)
- Removedproxy-from-env@1.1.0(transitive)
- Removedquerystring@0.2.1(transitive)