@memberjunction/auth-providers 0.0.1 → 5.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +4 -0
- package/CHANGELOG.md +10 -0
- package/dist/AuthProviderFactory.d.ts +68 -0
- package/dist/AuthProviderFactory.d.ts.map +1 -0
- package/dist/AuthProviderFactory.js +153 -0
- package/dist/AuthProviderFactory.js.map +1 -0
- package/dist/BaseAuthProvider.d.ts +41 -0
- package/dist/BaseAuthProvider.d.ts.map +1 -0
- package/dist/BaseAuthProvider.js +102 -0
- package/dist/BaseAuthProvider.js.map +1 -0
- package/dist/IAuthProvider.d.ts +46 -0
- package/dist/IAuthProvider.d.ts.map +1 -0
- package/dist/IAuthProvider.js +2 -0
- package/dist/IAuthProvider.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/providers/Auth0Provider.d.ts +18 -0
- package/dist/providers/Auth0Provider.d.ts.map +1 -0
- package/dist/providers/Auth0Provider.js +52 -0
- package/dist/providers/Auth0Provider.js.map +1 -0
- package/dist/providers/CognitoProvider.d.ts +18 -0
- package/dist/providers/CognitoProvider.d.ts.map +1 -0
- package/dist/providers/CognitoProvider.js +56 -0
- package/dist/providers/CognitoProvider.js.map +1 -0
- package/dist/providers/GoogleProvider.d.ts +18 -0
- package/dist/providers/GoogleProvider.d.ts.map +1 -0
- package/dist/providers/GoogleProvider.js +51 -0
- package/dist/providers/GoogleProvider.js.map +1 -0
- package/dist/providers/MSALProvider.d.ts +18 -0
- package/dist/providers/MSALProvider.d.ts.map +1 -0
- package/dist/providers/MSALProvider.js +52 -0
- package/dist/providers/MSALProvider.js.map +1 -0
- package/dist/providers/OktaProvider.d.ts +18 -0
- package/dist/providers/OktaProvider.d.ts.map +1 -0
- package/dist/providers/OktaProvider.js +52 -0
- package/dist/providers/OktaProvider.js.map +1 -0
- package/dist/tokenExpiredError.d.ts +5 -0
- package/dist/tokenExpiredError.d.ts.map +1 -0
- package/dist/tokenExpiredError.js +12 -0
- package/dist/tokenExpiredError.js.map +1 -0
- package/package.json +28 -7
- package/src/AuthProviderFactory.ts +180 -0
- package/src/BaseAuthProvider.ts +137 -0
- package/src/IAuthProvider.ts +54 -0
- package/src/index.ts +7 -0
- package/src/providers/Auth0Provider.ts +45 -0
- package/src/providers/CognitoProvider.ts +50 -0
- package/src/providers/GoogleProvider.ts +45 -0
- package/src/providers/MSALProvider.ts +45 -0
- package/src/providers/OktaProvider.ts +46 -0
- package/src/tokenExpiredError.ts +12 -0
- package/tsconfig.json +10 -0
- package/vitest.config.ts +11 -0
- package/README.md +0 -45
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { JwtHeader, JwtPayload, SigningKeyCallback } from 'jsonwebtoken';
|
|
2
|
+
import { AuthProviderConfig, AuthUserInfo } from '@memberjunction/core';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Interface for authentication providers in MemberJunction
|
|
6
|
+
* Enables support for any OAuth 2.0/OIDC compliant provider
|
|
7
|
+
*/
|
|
8
|
+
export interface IAuthProvider {
|
|
9
|
+
/**
|
|
10
|
+
* Unique name identifier for this provider
|
|
11
|
+
*/
|
|
12
|
+
name: string;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* The issuer URL for this provider (must match the 'iss' claim in tokens)
|
|
16
|
+
*/
|
|
17
|
+
issuer: string;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* The expected audience for tokens from this provider
|
|
21
|
+
*/
|
|
22
|
+
audience: string;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* The JWKS endpoint URL for retrieving signing keys
|
|
26
|
+
*/
|
|
27
|
+
jwksUri: string;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* OAuth client ID for this provider (optional, used by OAuth proxy for upstream authentication)
|
|
31
|
+
*/
|
|
32
|
+
clientId?: string;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Validates that the provider configuration is complete and valid
|
|
36
|
+
*/
|
|
37
|
+
validateConfig(): boolean;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Gets the signing key for token verification
|
|
41
|
+
*/
|
|
42
|
+
getSigningKey(header: JwtHeader, callback: SigningKeyCallback): void;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Extracts user information from the JWT payload
|
|
46
|
+
* Different providers use different claim names
|
|
47
|
+
*/
|
|
48
|
+
extractUserInfo(payload: JwtPayload): AuthUserInfo;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Checks if a given issuer URL belongs to this provider
|
|
52
|
+
*/
|
|
53
|
+
matchesIssuer(issuer: string): boolean;
|
|
54
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { IAuthProvider } from './IAuthProvider.js';
|
|
2
|
+
export { BaseAuthProvider } from './BaseAuthProvider.js';
|
|
3
|
+
export { AuthProviderFactory } from './AuthProviderFactory.js';
|
|
4
|
+
export { TokenExpiredError } from './tokenExpiredError.js';
|
|
5
|
+
|
|
6
|
+
// Re-export types consumers commonly need alongside the auth providers
|
|
7
|
+
export type { AuthProviderConfig, AuthUserInfo } from '@memberjunction/core';
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { JwtPayload } from 'jsonwebtoken';
|
|
2
|
+
import { RegisterClass } from '@memberjunction/global';
|
|
3
|
+
import { AuthProviderConfig, AuthUserInfo } from '@memberjunction/core';
|
|
4
|
+
import { BaseAuthProvider } from '../BaseAuthProvider.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Auth0 authentication provider implementation
|
|
8
|
+
*/
|
|
9
|
+
@RegisterClass(BaseAuthProvider, 'auth0')
|
|
10
|
+
export class Auth0Provider extends BaseAuthProvider {
|
|
11
|
+
constructor(config: AuthProviderConfig) {
|
|
12
|
+
super(config);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Extracts user information from Auth0 JWT payload
|
|
17
|
+
*/
|
|
18
|
+
extractUserInfo(payload: JwtPayload): AuthUserInfo {
|
|
19
|
+
// Auth0 uses standard OIDC claims
|
|
20
|
+
const email = payload.email as string | undefined;
|
|
21
|
+
const fullName = payload.name as string | undefined;
|
|
22
|
+
const firstName = payload.given_name as string | undefined;
|
|
23
|
+
const lastName = payload.family_name as string | undefined;
|
|
24
|
+
const preferredUsername = payload.preferred_username as string | undefined || email;
|
|
25
|
+
|
|
26
|
+
return {
|
|
27
|
+
email,
|
|
28
|
+
firstName: firstName || fullName?.split(' ')[0],
|
|
29
|
+
lastName: lastName || fullName?.split(' ')[1] || fullName?.split(' ')[0],
|
|
30
|
+
fullName,
|
|
31
|
+
preferredUsername
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Validates Auth0-specific configuration
|
|
37
|
+
*/
|
|
38
|
+
validateConfig(): boolean {
|
|
39
|
+
const baseValid = super.validateConfig();
|
|
40
|
+
const hasClientId = !!this.config.clientId;
|
|
41
|
+
const hasDomain = !!this.config.domain;
|
|
42
|
+
|
|
43
|
+
return baseValid && hasClientId && hasDomain;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { JwtPayload } from 'jsonwebtoken';
|
|
2
|
+
import { RegisterClass } from '@memberjunction/global';
|
|
3
|
+
import { AuthProviderConfig, AuthUserInfo } from '@memberjunction/core';
|
|
4
|
+
import { BaseAuthProvider } from '../BaseAuthProvider.js';
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* AWS Cognito authentication provider implementation
|
|
9
|
+
*/
|
|
10
|
+
@RegisterClass(BaseAuthProvider, 'cognito')
|
|
11
|
+
export class CognitoProvider extends BaseAuthProvider {
|
|
12
|
+
constructor(config: AuthProviderConfig) {
|
|
13
|
+
super(config);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Extracts user information from Cognito JWT payload
|
|
18
|
+
*/
|
|
19
|
+
extractUserInfo(payload: JwtPayload): AuthUserInfo {
|
|
20
|
+
// Cognito uses custom claims with 'cognito:' prefix for some fields
|
|
21
|
+
const email = payload.email as string | undefined ||
|
|
22
|
+
payload['cognito:username'] as string | undefined;
|
|
23
|
+
const fullName = payload.name as string | undefined;
|
|
24
|
+
const firstName = payload.given_name as string | undefined;
|
|
25
|
+
const lastName = payload.family_name as string | undefined;
|
|
26
|
+
const preferredUsername = payload['cognito:username'] as string | undefined ||
|
|
27
|
+
payload.preferred_username as string | undefined ||
|
|
28
|
+
email;
|
|
29
|
+
|
|
30
|
+
return {
|
|
31
|
+
email,
|
|
32
|
+
firstName: firstName || fullName?.split(' ')[0],
|
|
33
|
+
lastName: lastName || fullName?.split(' ')[1] || fullName?.split(' ')[0],
|
|
34
|
+
fullName,
|
|
35
|
+
preferredUsername
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Validates Cognito-specific configuration
|
|
41
|
+
*/
|
|
42
|
+
validateConfig(): boolean {
|
|
43
|
+
const baseValid = super.validateConfig();
|
|
44
|
+
const hasClientId = !!this.config.clientId;
|
|
45
|
+
const hasRegion = !!this.config.region;
|
|
46
|
+
const hasUserPoolId = !!this.config.userPoolId;
|
|
47
|
+
|
|
48
|
+
return baseValid && hasClientId && hasRegion && hasUserPoolId;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { JwtPayload } from 'jsonwebtoken';
|
|
2
|
+
import { RegisterClass } from '@memberjunction/global';
|
|
3
|
+
import { AuthProviderConfig, AuthUserInfo } from '@memberjunction/core';
|
|
4
|
+
import { BaseAuthProvider } from '../BaseAuthProvider.js';
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Google Identity Platform authentication provider implementation
|
|
9
|
+
*/
|
|
10
|
+
@RegisterClass(BaseAuthProvider, 'google')
|
|
11
|
+
export class GoogleProvider extends BaseAuthProvider {
|
|
12
|
+
constructor(config: AuthProviderConfig) {
|
|
13
|
+
super(config);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Extracts user information from Google JWT payload
|
|
18
|
+
*/
|
|
19
|
+
extractUserInfo(payload: JwtPayload): AuthUserInfo {
|
|
20
|
+
// Google uses standard OIDC claims
|
|
21
|
+
const email = payload.email as string | undefined;
|
|
22
|
+
const fullName = payload.name as string | undefined;
|
|
23
|
+
const firstName = payload.given_name as string | undefined;
|
|
24
|
+
const lastName = payload.family_name as string | undefined;
|
|
25
|
+
const preferredUsername = email; // Google typically uses email as username
|
|
26
|
+
|
|
27
|
+
return {
|
|
28
|
+
email,
|
|
29
|
+
firstName: firstName || fullName?.split(' ')[0],
|
|
30
|
+
lastName: lastName || fullName?.split(' ')[1] || fullName?.split(' ')[0],
|
|
31
|
+
fullName,
|
|
32
|
+
preferredUsername
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Validates Google-specific configuration
|
|
38
|
+
*/
|
|
39
|
+
validateConfig(): boolean {
|
|
40
|
+
const baseValid = super.validateConfig();
|
|
41
|
+
const hasClientId = !!this.config.clientId;
|
|
42
|
+
|
|
43
|
+
return baseValid && hasClientId;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { JwtPayload } from 'jsonwebtoken';
|
|
2
|
+
import { RegisterClass } from '@memberjunction/global';
|
|
3
|
+
import { AuthProviderConfig, AuthUserInfo } from '@memberjunction/core';
|
|
4
|
+
import { BaseAuthProvider } from '../BaseAuthProvider.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Microsoft Authentication Library (MSAL) provider implementation
|
|
8
|
+
*/
|
|
9
|
+
@RegisterClass(BaseAuthProvider, 'msal')
|
|
10
|
+
export class MSALProvider extends BaseAuthProvider {
|
|
11
|
+
constructor(config: AuthProviderConfig) {
|
|
12
|
+
super(config);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Extracts user information from MSAL/Azure AD JWT payload
|
|
17
|
+
*/
|
|
18
|
+
extractUserInfo(payload: JwtPayload): AuthUserInfo {
|
|
19
|
+
// MSAL/Azure AD uses some custom claims
|
|
20
|
+
const email = payload.email as string | undefined || payload.preferred_username as string | undefined;
|
|
21
|
+
const fullName = payload.name as string | undefined;
|
|
22
|
+
const firstName = payload.given_name as string | undefined;
|
|
23
|
+
const lastName = payload.family_name as string | undefined;
|
|
24
|
+
const preferredUsername = payload.preferred_username as string | undefined;
|
|
25
|
+
|
|
26
|
+
return {
|
|
27
|
+
email,
|
|
28
|
+
firstName: firstName || fullName?.split(' ')[0],
|
|
29
|
+
lastName: lastName || fullName?.split(' ')[1] || fullName?.split(' ')[0],
|
|
30
|
+
fullName,
|
|
31
|
+
preferredUsername
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Validates MSAL-specific configuration
|
|
37
|
+
*/
|
|
38
|
+
validateConfig(): boolean {
|
|
39
|
+
const baseValid = super.validateConfig();
|
|
40
|
+
const hasClientId = !!this.config.clientId;
|
|
41
|
+
const hasTenantId = !!this.config.tenantId;
|
|
42
|
+
|
|
43
|
+
return baseValid && hasClientId && hasTenantId;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { JwtPayload } from 'jsonwebtoken';
|
|
2
|
+
import { RegisterClass } from '@memberjunction/global';
|
|
3
|
+
import { AuthProviderConfig, AuthUserInfo } from '@memberjunction/core';
|
|
4
|
+
import { BaseAuthProvider } from '../BaseAuthProvider.js';
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Okta authentication provider implementation
|
|
9
|
+
*/
|
|
10
|
+
@RegisterClass(BaseAuthProvider, 'okta')
|
|
11
|
+
export class OktaProvider extends BaseAuthProvider {
|
|
12
|
+
constructor(config: AuthProviderConfig) {
|
|
13
|
+
super(config);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Extracts user information from Okta JWT payload
|
|
18
|
+
*/
|
|
19
|
+
extractUserInfo(payload: JwtPayload): AuthUserInfo {
|
|
20
|
+
// Okta uses standard OIDC claims plus some custom ones
|
|
21
|
+
const email = payload.email as string | undefined || payload.preferred_username as string | undefined;
|
|
22
|
+
const fullName = payload.name as string | undefined;
|
|
23
|
+
const firstName = payload.given_name as string | undefined;
|
|
24
|
+
const lastName = payload.family_name as string | undefined;
|
|
25
|
+
const preferredUsername = payload.preferred_username as string | undefined || email;
|
|
26
|
+
|
|
27
|
+
return {
|
|
28
|
+
email,
|
|
29
|
+
firstName: firstName || fullName?.split(' ')[0],
|
|
30
|
+
lastName: lastName || fullName?.split(' ')[1] || fullName?.split(' ')[0],
|
|
31
|
+
fullName,
|
|
32
|
+
preferredUsername
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Validates Okta-specific configuration
|
|
38
|
+
*/
|
|
39
|
+
validateConfig(): boolean {
|
|
40
|
+
const baseValid = super.validateConfig();
|
|
41
|
+
const hasClientId = !!this.config.clientId;
|
|
42
|
+
const hasDomain = !!this.config.domain;
|
|
43
|
+
|
|
44
|
+
return baseValid && hasClientId && hasDomain;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { GraphQLError } from 'graphql';
|
|
2
|
+
|
|
3
|
+
export class TokenExpiredError extends GraphQLError {
|
|
4
|
+
constructor(expiryDate: Date, message = 'The provided token has expired. Please authenticate again.') {
|
|
5
|
+
super(message, {
|
|
6
|
+
extensions: {
|
|
7
|
+
code: 'JWT_EXPIRED',
|
|
8
|
+
expiryDate: expiryDate.toISOString(),
|
|
9
|
+
},
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "../../tsconfig.server.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"outDir": "dist",
|
|
5
|
+
"rootDir": "src",
|
|
6
|
+
"module": "es2022"
|
|
7
|
+
},
|
|
8
|
+
"include": ["src/**/*"],
|
|
9
|
+
"exclude": ["node_modules", "src/__tests__/**", "src/**/*.test.ts", "src/**/*.spec.ts", "vitest.config.ts"]
|
|
10
|
+
}
|
package/vitest.config.ts
ADDED
package/README.md
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
# @memberjunction/auth-providers
|
|
2
|
-
|
|
3
|
-
## ⚠️ IMPORTANT NOTICE ⚠️
|
|
4
|
-
|
|
5
|
-
**This package is created solely for the purpose of setting up OIDC (OpenID Connect) trusted publishing with npm.**
|
|
6
|
-
|
|
7
|
-
This is **NOT** a functional package and contains **NO** code or functionality beyond the OIDC setup configuration.
|
|
8
|
-
|
|
9
|
-
## Purpose
|
|
10
|
-
|
|
11
|
-
This package exists to:
|
|
12
|
-
1. Configure OIDC trusted publishing for the package name `@memberjunction/auth-providers`
|
|
13
|
-
2. Enable secure, token-less publishing from CI/CD workflows
|
|
14
|
-
3. Establish provenance for packages published under this name
|
|
15
|
-
|
|
16
|
-
## What is OIDC Trusted Publishing?
|
|
17
|
-
|
|
18
|
-
OIDC trusted publishing allows package maintainers to publish packages directly from their CI/CD workflows without needing to manage npm access tokens. Instead, it uses OpenID Connect to establish trust between the CI/CD provider (like GitHub Actions) and npm.
|
|
19
|
-
|
|
20
|
-
## Setup Instructions
|
|
21
|
-
|
|
22
|
-
To properly configure OIDC trusted publishing for this package:
|
|
23
|
-
|
|
24
|
-
1. Go to [npmjs.com](https://www.npmjs.com/) and navigate to your package settings
|
|
25
|
-
2. Configure the trusted publisher (e.g., GitHub Actions)
|
|
26
|
-
3. Specify the repository and workflow that should be allowed to publish
|
|
27
|
-
4. Use the configured workflow to publish your actual package
|
|
28
|
-
|
|
29
|
-
## DO NOT USE THIS PACKAGE
|
|
30
|
-
|
|
31
|
-
This package is a placeholder for OIDC configuration only. It:
|
|
32
|
-
- Contains no executable code
|
|
33
|
-
- Provides no functionality
|
|
34
|
-
- Should not be installed as a dependency
|
|
35
|
-
- Exists only for administrative purposes
|
|
36
|
-
|
|
37
|
-
## More Information
|
|
38
|
-
|
|
39
|
-
For more details about npm's trusted publishing feature, see:
|
|
40
|
-
- [npm Trusted Publishing Documentation](https://docs.npmjs.com/generating-provenance-statements)
|
|
41
|
-
- [GitHub Actions OIDC Documentation](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect)
|
|
42
|
-
|
|
43
|
-
---
|
|
44
|
-
|
|
45
|
-
**Maintained for OIDC setup purposes only**
|