@ainetwork/adk-provider-auth-m365 0.7.1 → 0.7.2
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/dist/{chunk-4LXYNIZV.js → chunk-O2NTTHIX.js} +7 -3
- package/dist/chunk-O2NTTHIX.js.map +1 -0
- package/dist/implements/m365.auth.cjs +6 -2
- package/dist/implements/m365.auth.cjs.map +1 -1
- package/dist/implements/m365.auth.js +1 -1
- package/dist/index.cjs +6 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -1
- package/implements/m365.auth.ts +8 -1
- package/package.json +3 -3
- package/dist/chunk-4LXYNIZV.js.map +0 -1
|
@@ -92,7 +92,8 @@ var M365Auth = class extends AuthModule {
|
|
|
92
92
|
if (payload2.sub) {
|
|
93
93
|
return {
|
|
94
94
|
isAuthenticated: true,
|
|
95
|
-
userId: payload2.sub
|
|
95
|
+
userId: payload2.sub,
|
|
96
|
+
email: payload2.userPrincipalName || payload2.email
|
|
96
97
|
};
|
|
97
98
|
}
|
|
98
99
|
} catch {
|
|
@@ -105,7 +106,10 @@ var M365Auth = class extends AuthModule {
|
|
|
105
106
|
}
|
|
106
107
|
return {
|
|
107
108
|
isAuthenticated: true,
|
|
108
|
-
userId: payload.oid || payload.sub
|
|
109
|
+
userId: payload.oid || payload.sub,
|
|
110
|
+
// userPrincipalName carries the email. Use it directly if present,
|
|
111
|
+
// else the UPN-equivalent claim (preferred_username v2.0 / upn v1.0), else email.
|
|
112
|
+
email: payload.userPrincipalName || payload.preferred_username || payload.upn || payload.email
|
|
109
113
|
};
|
|
110
114
|
} catch (err) {
|
|
111
115
|
console.error("M365 auth verification failed:", err.message);
|
|
@@ -124,4 +128,4 @@ var M365Auth = class extends AuthModule {
|
|
|
124
128
|
export {
|
|
125
129
|
M365Auth
|
|
126
130
|
};
|
|
127
|
-
//# sourceMappingURL=chunk-
|
|
131
|
+
//# sourceMappingURL=chunk-O2NTTHIX.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../implements/m365.auth.ts"],"sourcesContent":["import { AuthModule } from \"@ainetwork/adk/modules\";\nimport { AuthResponse } from \"@ainetwork/adk/types/auth\";\nimport type { Request } from \"express\";\nimport jwt, { JwtHeader, SigningKeyCallback } from \"jsonwebtoken\";\nimport jwksClient from \"jwks-rsa\";\n\nexport interface M365AuthConfig {\n clientId: string;\n tenantId: string;\n cloudInstance?: string;\n nextAuthSecret?: string;\n}\n\ninterface AzureADTokenPayload {\n aud: string;\n iss: string;\n iat: number;\n nbf: number;\n exp: number;\n oid?: string;\n sub?: string;\n tid?: string;\n appid?: string;\n azp?: string;\n userPrincipalName?: string; // explicit UPN claim when present\n upn?: string; // userPrincipalName (Azure AD v1.0 tokens)\n preferred_username?: string; // UPN-equivalent in v2.0 tokens\n email?: string;\n name?: string;\n}\n\ninterface NextAuthJWTPayload {\n name?: string;\n email?: string;\n userPrincipalName?: string; // set by the WISE NextAuth jwt callback\n picture?: string;\n sub: string;\n iat: number;\n exp: number;\n jti?: string;\n}\n\nexport class M365Auth extends AuthModule {\n private readonly jwksClient: jwksClient.JwksClient;\n private readonly cloudInstance: string;\n private readonly expectedIssuers: [string, ...string[]];\n\n constructor(private readonly config: M365AuthConfig) {\n super();\n this.cloudInstance = this.config.cloudInstance || \"https://login.microsoftonline.com\";\n // Support both v1.0 and v2.0 issuers\n this.expectedIssuers = [\n `${this.cloudInstance}/${this.config.tenantId}/v2.0`,\n `https://sts.windows.net/${this.config.tenantId}/`,\n ] as [string, ...string[]];\n\n this.jwksClient = jwksClient({\n jwksUri: `${this.cloudInstance}/${this.config.tenantId}/discovery/v2.0/keys`,\n cache: true,\n cacheMaxAge: 86400000, // 24 hours\n rateLimit: true,\n jwksRequestsPerMinute: 10,\n });\n }\n\n private getSigningKey = (header: JwtHeader, callback: SigningKeyCallback): void => {\n this.jwksClient.getSigningKey(header.kid, (err, key) => {\n if (err) {\n callback(err);\n return;\n }\n const signingKey = key?.getPublicKey();\n callback(null, signingKey);\n });\n };\n\n private verifyAzureADToken(token: string): Promise<AzureADTokenPayload> {\n return new Promise((resolve, reject) => {\n jwt.verify(\n token,\n this.getSigningKey,\n {\n algorithms: [\"RS256\"],\n issuer: this.expectedIssuers,\n },\n (err: Error | null, decoded: unknown) => {\n if (err) {\n reject(err);\n return;\n }\n\n const payload = decoded as AzureADTokenPayload;\n\n // For Access Tokens, verify appid or azp matches clientId\n // For ID Tokens, verify aud matches clientId\n const appId = payload.appid || payload.azp;\n if (payload.aud !== this.config.clientId && appId !== this.config.clientId) {\n reject(new Error(\"Token was not issued for this client\"));\n return;\n }\n\n resolve(payload);\n }\n );\n });\n }\n\n private verifyNextAuthToken(token: string): Promise<NextAuthJWTPayload> {\n return new Promise((resolve, reject) => {\n if (!this.config.nextAuthSecret) {\n reject(new Error(\"NextAuth secret is required for NextAuth token verification\"));\n return;\n }\n\n jwt.verify(\n token,\n this.config.nextAuthSecret,\n {\n algorithms: [\"HS256\"],\n },\n (err: Error | null, decoded: unknown) => {\n if (err) {\n reject(err);\n return;\n }\n resolve(decoded as NextAuthJWTPayload);\n }\n );\n });\n }\n\n public async authenticate(req: any, res: any): Promise<AuthResponse> {\n const token = this.extractBearerToken(req);\n if (!token) {\n return { isAuthenticated: false };\n }\n\n try {\n // First, try to verify as NextAuth JWT token (signed with NEXTAUTH_SECRET)\n if (this.config.nextAuthSecret) {\n try {\n const payload = await this.verifyNextAuthToken(token);\n if (payload.sub) {\n return {\n isAuthenticated: true,\n userId: payload.sub,\n email: payload.userPrincipalName || payload.email,\n };\n }\n } catch {\n // If NextAuth verification fails, try Azure AD token verification\n }\n }\n\n // Try to verify as Azure AD token\n const payload = await this.verifyAzureADToken(token);\n\n if (!payload.oid && !payload.sub) {\n console.error(\"M365 auth verification failed: Token does not contain oid or sub claim\");\n return { isAuthenticated: false };\n }\n\n return {\n isAuthenticated: true,\n userId: (payload.oid || payload.sub) as string,\n // userPrincipalName carries the email. Use it directly if present,\n // else the UPN-equivalent claim (preferred_username v2.0 / upn v1.0), else email.\n email: payload.userPrincipalName || payload.preferred_username || payload.upn || payload.email,\n };\n } catch (err) {\n console.error(\"M365 auth verification failed:\", (err as Error).message);\n return { isAuthenticated: false };\n }\n }\n\n private extractBearerToken(req: Request): string | null {\n const authHeader = req.headers.authorization;\n if (!authHeader?.startsWith(\"Bearer \")) {\n return null;\n }\n return authHeader.substring(7);\n }\n}\n"],"mappings":"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","names":["payload"]}
|
|
@@ -126,7 +126,8 @@ var M365Auth = class extends import_modules.AuthModule {
|
|
|
126
126
|
if (payload2.sub) {
|
|
127
127
|
return {
|
|
128
128
|
isAuthenticated: true,
|
|
129
|
-
userId: payload2.sub
|
|
129
|
+
userId: payload2.sub,
|
|
130
|
+
email: payload2.userPrincipalName || payload2.email
|
|
130
131
|
};
|
|
131
132
|
}
|
|
132
133
|
} catch {
|
|
@@ -139,7 +140,10 @@ var M365Auth = class extends import_modules.AuthModule {
|
|
|
139
140
|
}
|
|
140
141
|
return {
|
|
141
142
|
isAuthenticated: true,
|
|
142
|
-
userId: payload.oid || payload.sub
|
|
143
|
+
userId: payload.oid || payload.sub,
|
|
144
|
+
// userPrincipalName carries the email. Use it directly if present,
|
|
145
|
+
// else the UPN-equivalent claim (preferred_username v2.0 / upn v1.0), else email.
|
|
146
|
+
email: payload.userPrincipalName || payload.preferred_username || payload.upn || payload.email
|
|
143
147
|
};
|
|
144
148
|
} catch (err) {
|
|
145
149
|
console.error("M365 auth verification failed:", err.message);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../implements/m365.auth.ts"],"sourcesContent":["import { AuthModule } from \"@ainetwork/adk/modules\";\nimport { AuthResponse } from \"@ainetwork/adk/types/auth\";\nimport type { Request } from \"express\";\nimport jwt, { JwtHeader, SigningKeyCallback } from \"jsonwebtoken\";\nimport jwksClient from \"jwks-rsa\";\n\nexport interface M365AuthConfig {\n clientId: string;\n tenantId: string;\n cloudInstance?: string;\n nextAuthSecret?: string;\n}\n\ninterface AzureADTokenPayload {\n aud: string;\n iss: string;\n iat: number;\n nbf: number;\n exp: number;\n oid?: string;\n sub?: string;\n tid?: string;\n appid?: string;\n azp?: string;\n preferred_username?: string
|
|
1
|
+
{"version":3,"sources":["../../implements/m365.auth.ts"],"sourcesContent":["import { AuthModule } from \"@ainetwork/adk/modules\";\nimport { AuthResponse } from \"@ainetwork/adk/types/auth\";\nimport type { Request } from \"express\";\nimport jwt, { JwtHeader, SigningKeyCallback } from \"jsonwebtoken\";\nimport jwksClient from \"jwks-rsa\";\n\nexport interface M365AuthConfig {\n clientId: string;\n tenantId: string;\n cloudInstance?: string;\n nextAuthSecret?: string;\n}\n\ninterface AzureADTokenPayload {\n aud: string;\n iss: string;\n iat: number;\n nbf: number;\n exp: number;\n oid?: string;\n sub?: string;\n tid?: string;\n appid?: string;\n azp?: string;\n userPrincipalName?: string; // explicit UPN claim when present\n upn?: string; // userPrincipalName (Azure AD v1.0 tokens)\n preferred_username?: string; // UPN-equivalent in v2.0 tokens\n email?: string;\n name?: string;\n}\n\ninterface NextAuthJWTPayload {\n name?: string;\n email?: string;\n userPrincipalName?: string; // set by the WISE NextAuth jwt callback\n picture?: string;\n sub: string;\n iat: number;\n exp: number;\n jti?: string;\n}\n\nexport class M365Auth extends AuthModule {\n private readonly jwksClient: jwksClient.JwksClient;\n private readonly cloudInstance: string;\n private readonly expectedIssuers: [string, ...string[]];\n\n constructor(private readonly config: M365AuthConfig) {\n super();\n this.cloudInstance = this.config.cloudInstance || \"https://login.microsoftonline.com\";\n // Support both v1.0 and v2.0 issuers\n this.expectedIssuers = [\n `${this.cloudInstance}/${this.config.tenantId}/v2.0`,\n `https://sts.windows.net/${this.config.tenantId}/`,\n ] as [string, ...string[]];\n\n this.jwksClient = jwksClient({\n jwksUri: `${this.cloudInstance}/${this.config.tenantId}/discovery/v2.0/keys`,\n cache: true,\n cacheMaxAge: 86400000, // 24 hours\n rateLimit: true,\n jwksRequestsPerMinute: 10,\n });\n }\n\n private getSigningKey = (header: JwtHeader, callback: SigningKeyCallback): void => {\n this.jwksClient.getSigningKey(header.kid, (err, key) => {\n if (err) {\n callback(err);\n return;\n }\n const signingKey = key?.getPublicKey();\n callback(null, signingKey);\n });\n };\n\n private verifyAzureADToken(token: string): Promise<AzureADTokenPayload> {\n return new Promise((resolve, reject) => {\n jwt.verify(\n token,\n this.getSigningKey,\n {\n algorithms: [\"RS256\"],\n issuer: this.expectedIssuers,\n },\n (err: Error | null, decoded: unknown) => {\n if (err) {\n reject(err);\n return;\n }\n\n const payload = decoded as AzureADTokenPayload;\n\n // For Access Tokens, verify appid or azp matches clientId\n // For ID Tokens, verify aud matches clientId\n const appId = payload.appid || payload.azp;\n if (payload.aud !== this.config.clientId && appId !== this.config.clientId) {\n reject(new Error(\"Token was not issued for this client\"));\n return;\n }\n\n resolve(payload);\n }\n );\n });\n }\n\n private verifyNextAuthToken(token: string): Promise<NextAuthJWTPayload> {\n return new Promise((resolve, reject) => {\n if (!this.config.nextAuthSecret) {\n reject(new Error(\"NextAuth secret is required for NextAuth token verification\"));\n return;\n }\n\n jwt.verify(\n token,\n this.config.nextAuthSecret,\n {\n algorithms: [\"HS256\"],\n },\n (err: Error | null, decoded: unknown) => {\n if (err) {\n reject(err);\n return;\n }\n resolve(decoded as NextAuthJWTPayload);\n }\n );\n });\n }\n\n public async authenticate(req: any, res: any): Promise<AuthResponse> {\n const token = this.extractBearerToken(req);\n if (!token) {\n return { isAuthenticated: false };\n }\n\n try {\n // First, try to verify as NextAuth JWT token (signed with NEXTAUTH_SECRET)\n if (this.config.nextAuthSecret) {\n try {\n const payload = await this.verifyNextAuthToken(token);\n if (payload.sub) {\n return {\n isAuthenticated: true,\n userId: payload.sub,\n email: payload.userPrincipalName || payload.email,\n };\n }\n } catch {\n // If NextAuth verification fails, try Azure AD token verification\n }\n }\n\n // Try to verify as Azure AD token\n const payload = await this.verifyAzureADToken(token);\n\n if (!payload.oid && !payload.sub) {\n console.error(\"M365 auth verification failed: Token does not contain oid or sub claim\");\n return { isAuthenticated: false };\n }\n\n return {\n isAuthenticated: true,\n userId: (payload.oid || payload.sub) as string,\n // userPrincipalName carries the email. Use it directly if present,\n // else the UPN-equivalent claim (preferred_username v2.0 / upn v1.0), else email.\n email: payload.userPrincipalName || payload.preferred_username || payload.upn || payload.email,\n };\n } catch (err) {\n console.error(\"M365 auth verification failed:\", (err as Error).message);\n return { isAuthenticated: false };\n }\n }\n\n private extractBearerToken(req: Request): string | null {\n const authHeader = req.headers.authorization;\n if (!authHeader?.startsWith(\"Bearer \")) {\n return null;\n }\n return authHeader.substring(7);\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qBAA2B;AAG3B,0BAAmD;AACnD,sBAAuB;AAsChB,IAAM,WAAN,cAAuB,0BAAW;AAAA,EAKvC,YAA6B,QAAwB;AACnD,UAAM;AADqB;AAE3B,SAAK,gBAAgB,KAAK,OAAO,iBAAiB;AAElD,SAAK,kBAAkB;AAAA,MACrB,GAAG,KAAK,aAAa,IAAI,KAAK,OAAO,QAAQ;AAAA,MAC7C,2BAA2B,KAAK,OAAO,QAAQ;AAAA,IACjD;AAEA,SAAK,iBAAa,gBAAAA,SAAW;AAAA,MAC3B,SAAS,GAAG,KAAK,aAAa,IAAI,KAAK,OAAO,QAAQ;AAAA,MACtD,OAAO;AAAA,MACP,aAAa;AAAA;AAAA,MACb,WAAW;AAAA,MACX,uBAAuB;AAAA,IACzB,CAAC;AAAA,EACH;AAAA,EApBiB;AAAA,EACA;AAAA,EACA;AAAA,EAoBT,gBAAgB,CAAC,QAAmB,aAAuC;AACjF,SAAK,WAAW,cAAc,OAAO,KAAK,CAAC,KAAK,QAAQ;AACtD,UAAI,KAAK;AACP,iBAAS,GAAG;AACZ;AAAA,MACF;AACA,YAAM,aAAa,KAAK,aAAa;AACrC,eAAS,MAAM,UAAU;AAAA,IAC3B,CAAC;AAAA,EACH;AAAA,EAEQ,mBAAmB,OAA6C;AACtE,WAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,0BAAAC,QAAI;AAAA,QACF;AAAA,QACA,KAAK;AAAA,QACL;AAAA,UACE,YAAY,CAAC,OAAO;AAAA,UACpB,QAAQ,KAAK;AAAA,QACf;AAAA,QACA,CAAC,KAAmB,YAAqB;AACvC,cAAI,KAAK;AACP,mBAAO,GAAG;AACV;AAAA,UACF;AAEA,gBAAM,UAAU;AAIhB,gBAAM,QAAQ,QAAQ,SAAS,QAAQ;AACvC,cAAI,QAAQ,QAAQ,KAAK,OAAO,YAAY,UAAU,KAAK,OAAO,UAAU;AAC1E,mBAAO,IAAI,MAAM,sCAAsC,CAAC;AACxD;AAAA,UACF;AAEA,kBAAQ,OAAO;AAAA,QACjB;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEQ,oBAAoB,OAA4C;AACtE,WAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,UAAI,CAAC,KAAK,OAAO,gBAAgB;AAC/B,eAAO,IAAI,MAAM,6DAA6D,CAAC;AAC/E;AAAA,MACF;AAEA,0BAAAA,QAAI;AAAA,QACF;AAAA,QACA,KAAK,OAAO;AAAA,QACZ;AAAA,UACE,YAAY,CAAC,OAAO;AAAA,QACtB;AAAA,QACA,CAAC,KAAmB,YAAqB;AACvC,cAAI,KAAK;AACP,mBAAO,GAAG;AACV;AAAA,UACF;AACA,kBAAQ,OAA6B;AAAA,QACvC;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,MAAa,aAAa,KAAU,KAAiC;AACnE,UAAM,QAAQ,KAAK,mBAAmB,GAAG;AACzC,QAAI,CAAC,OAAO;AACV,aAAO,EAAE,iBAAiB,MAAM;AAAA,IAClC;AAEA,QAAI;AAEF,UAAI,KAAK,OAAO,gBAAgB;AAC9B,YAAI;AACF,gBAAMC,WAAU,MAAM,KAAK,oBAAoB,KAAK;AACpD,cAAIA,SAAQ,KAAK;AACf,mBAAO;AAAA,cACL,iBAAiB;AAAA,cACjB,QAAQA,SAAQ;AAAA,cAChB,OAAOA,SAAQ,qBAAqBA,SAAQ;AAAA,YAC9C;AAAA,UACF;AAAA,QACF,QAAQ;AAAA,QAER;AAAA,MACF;AAGA,YAAM,UAAU,MAAM,KAAK,mBAAmB,KAAK;AAEnD,UAAI,CAAC,QAAQ,OAAO,CAAC,QAAQ,KAAK;AAChC,gBAAQ,MAAM,wEAAwE;AACtF,eAAO,EAAE,iBAAiB,MAAM;AAAA,MAClC;AAEA,aAAO;AAAA,QACL,iBAAiB;AAAA,QACjB,QAAS,QAAQ,OAAO,QAAQ;AAAA;AAAA;AAAA,QAGhC,OAAO,QAAQ,qBAAqB,QAAQ,sBAAsB,QAAQ,OAAO,QAAQ;AAAA,MAC3F;AAAA,IACF,SAAS,KAAK;AACZ,cAAQ,MAAM,kCAAmC,IAAc,OAAO;AACtE,aAAO,EAAE,iBAAiB,MAAM;AAAA,IAClC;AAAA,EACF;AAAA,EAEQ,mBAAmB,KAA6B;AACtD,UAAM,aAAa,IAAI,QAAQ;AAC/B,QAAI,CAAC,YAAY,WAAW,SAAS,GAAG;AACtC,aAAO;AAAA,IACT;AACA,WAAO,WAAW,UAAU,CAAC;AAAA,EAC/B;AACF;","names":["jwksClient","jwt","payload"]}
|
package/dist/index.cjs
CHANGED
|
@@ -128,7 +128,8 @@ var M365Auth = class extends import_modules.AuthModule {
|
|
|
128
128
|
if (payload2.sub) {
|
|
129
129
|
return {
|
|
130
130
|
isAuthenticated: true,
|
|
131
|
-
userId: payload2.sub
|
|
131
|
+
userId: payload2.sub,
|
|
132
|
+
email: payload2.userPrincipalName || payload2.email
|
|
132
133
|
};
|
|
133
134
|
}
|
|
134
135
|
} catch {
|
|
@@ -141,7 +142,10 @@ var M365Auth = class extends import_modules.AuthModule {
|
|
|
141
142
|
}
|
|
142
143
|
return {
|
|
143
144
|
isAuthenticated: true,
|
|
144
|
-
userId: payload.oid || payload.sub
|
|
145
|
+
userId: payload.oid || payload.sub,
|
|
146
|
+
// userPrincipalName carries the email. Use it directly if present,
|
|
147
|
+
// else the UPN-equivalent claim (preferred_username v2.0 / upn v1.0), else email.
|
|
148
|
+
email: payload.userPrincipalName || payload.preferred_username || payload.upn || payload.email
|
|
145
149
|
};
|
|
146
150
|
} catch (err) {
|
|
147
151
|
console.error("M365 auth verification failed:", err.message);
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../index.ts","../implements/m365.auth.ts"],"sourcesContent":["export { M365Auth, type M365AuthConfig } from \"./implements/m365.auth\";\n","import { AuthModule } from \"@ainetwork/adk/modules\";\nimport { AuthResponse } from \"@ainetwork/adk/types/auth\";\nimport type { Request } from \"express\";\nimport jwt, { JwtHeader, SigningKeyCallback } from \"jsonwebtoken\";\nimport jwksClient from \"jwks-rsa\";\n\nexport interface M365AuthConfig {\n clientId: string;\n tenantId: string;\n cloudInstance?: string;\n nextAuthSecret?: string;\n}\n\ninterface AzureADTokenPayload {\n aud: string;\n iss: string;\n iat: number;\n nbf: number;\n exp: number;\n oid?: string;\n sub?: string;\n tid?: string;\n appid?: string;\n azp?: string;\n preferred_username?: string
|
|
1
|
+
{"version":3,"sources":["../index.ts","../implements/m365.auth.ts"],"sourcesContent":["export { M365Auth, type M365AuthConfig } from \"./implements/m365.auth\";\n","import { AuthModule } from \"@ainetwork/adk/modules\";\nimport { AuthResponse } from \"@ainetwork/adk/types/auth\";\nimport type { Request } from \"express\";\nimport jwt, { JwtHeader, SigningKeyCallback } from \"jsonwebtoken\";\nimport jwksClient from \"jwks-rsa\";\n\nexport interface M365AuthConfig {\n clientId: string;\n tenantId: string;\n cloudInstance?: string;\n nextAuthSecret?: string;\n}\n\ninterface AzureADTokenPayload {\n aud: string;\n iss: string;\n iat: number;\n nbf: number;\n exp: number;\n oid?: string;\n sub?: string;\n tid?: string;\n appid?: string;\n azp?: string;\n userPrincipalName?: string; // explicit UPN claim when present\n upn?: string; // userPrincipalName (Azure AD v1.0 tokens)\n preferred_username?: string; // UPN-equivalent in v2.0 tokens\n email?: string;\n name?: string;\n}\n\ninterface NextAuthJWTPayload {\n name?: string;\n email?: string;\n userPrincipalName?: string; // set by the WISE NextAuth jwt callback\n picture?: string;\n sub: string;\n iat: number;\n exp: number;\n jti?: string;\n}\n\nexport class M365Auth extends AuthModule {\n private readonly jwksClient: jwksClient.JwksClient;\n private readonly cloudInstance: string;\n private readonly expectedIssuers: [string, ...string[]];\n\n constructor(private readonly config: M365AuthConfig) {\n super();\n this.cloudInstance = this.config.cloudInstance || \"https://login.microsoftonline.com\";\n // Support both v1.0 and v2.0 issuers\n this.expectedIssuers = [\n `${this.cloudInstance}/${this.config.tenantId}/v2.0`,\n `https://sts.windows.net/${this.config.tenantId}/`,\n ] as [string, ...string[]];\n\n this.jwksClient = jwksClient({\n jwksUri: `${this.cloudInstance}/${this.config.tenantId}/discovery/v2.0/keys`,\n cache: true,\n cacheMaxAge: 86400000, // 24 hours\n rateLimit: true,\n jwksRequestsPerMinute: 10,\n });\n }\n\n private getSigningKey = (header: JwtHeader, callback: SigningKeyCallback): void => {\n this.jwksClient.getSigningKey(header.kid, (err, key) => {\n if (err) {\n callback(err);\n return;\n }\n const signingKey = key?.getPublicKey();\n callback(null, signingKey);\n });\n };\n\n private verifyAzureADToken(token: string): Promise<AzureADTokenPayload> {\n return new Promise((resolve, reject) => {\n jwt.verify(\n token,\n this.getSigningKey,\n {\n algorithms: [\"RS256\"],\n issuer: this.expectedIssuers,\n },\n (err: Error | null, decoded: unknown) => {\n if (err) {\n reject(err);\n return;\n }\n\n const payload = decoded as AzureADTokenPayload;\n\n // For Access Tokens, verify appid or azp matches clientId\n // For ID Tokens, verify aud matches clientId\n const appId = payload.appid || payload.azp;\n if (payload.aud !== this.config.clientId && appId !== this.config.clientId) {\n reject(new Error(\"Token was not issued for this client\"));\n return;\n }\n\n resolve(payload);\n }\n );\n });\n }\n\n private verifyNextAuthToken(token: string): Promise<NextAuthJWTPayload> {\n return new Promise((resolve, reject) => {\n if (!this.config.nextAuthSecret) {\n reject(new Error(\"NextAuth secret is required for NextAuth token verification\"));\n return;\n }\n\n jwt.verify(\n token,\n this.config.nextAuthSecret,\n {\n algorithms: [\"HS256\"],\n },\n (err: Error | null, decoded: unknown) => {\n if (err) {\n reject(err);\n return;\n }\n resolve(decoded as NextAuthJWTPayload);\n }\n );\n });\n }\n\n public async authenticate(req: any, res: any): Promise<AuthResponse> {\n const token = this.extractBearerToken(req);\n if (!token) {\n return { isAuthenticated: false };\n }\n\n try {\n // First, try to verify as NextAuth JWT token (signed with NEXTAUTH_SECRET)\n if (this.config.nextAuthSecret) {\n try {\n const payload = await this.verifyNextAuthToken(token);\n if (payload.sub) {\n return {\n isAuthenticated: true,\n userId: payload.sub,\n email: payload.userPrincipalName || payload.email,\n };\n }\n } catch {\n // If NextAuth verification fails, try Azure AD token verification\n }\n }\n\n // Try to verify as Azure AD token\n const payload = await this.verifyAzureADToken(token);\n\n if (!payload.oid && !payload.sub) {\n console.error(\"M365 auth verification failed: Token does not contain oid or sub claim\");\n return { isAuthenticated: false };\n }\n\n return {\n isAuthenticated: true,\n userId: (payload.oid || payload.sub) as string,\n // userPrincipalName carries the email. Use it directly if present,\n // else the UPN-equivalent claim (preferred_username v2.0 / upn v1.0), else email.\n email: payload.userPrincipalName || payload.preferred_username || payload.upn || payload.email,\n };\n } catch (err) {\n console.error(\"M365 auth verification failed:\", (err as Error).message);\n return { isAuthenticated: false };\n }\n }\n\n private extractBearerToken(req: Request): string | null {\n const authHeader = req.headers.authorization;\n if (!authHeader?.startsWith(\"Bearer \")) {\n return null;\n }\n return authHeader.substring(7);\n }\n}\n"],"mappings":"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","names":["jwksClient","jwt","payload"]}
|
package/dist/index.js
CHANGED
package/implements/m365.auth.ts
CHANGED
|
@@ -22,7 +22,9 @@ interface AzureADTokenPayload {
|
|
|
22
22
|
tid?: string;
|
|
23
23
|
appid?: string;
|
|
24
24
|
azp?: string;
|
|
25
|
-
|
|
25
|
+
userPrincipalName?: string; // explicit UPN claim when present
|
|
26
|
+
upn?: string; // userPrincipalName (Azure AD v1.0 tokens)
|
|
27
|
+
preferred_username?: string; // UPN-equivalent in v2.0 tokens
|
|
26
28
|
email?: string;
|
|
27
29
|
name?: string;
|
|
28
30
|
}
|
|
@@ -30,6 +32,7 @@ interface AzureADTokenPayload {
|
|
|
30
32
|
interface NextAuthJWTPayload {
|
|
31
33
|
name?: string;
|
|
32
34
|
email?: string;
|
|
35
|
+
userPrincipalName?: string; // set by the WISE NextAuth jwt callback
|
|
33
36
|
picture?: string;
|
|
34
37
|
sub: string;
|
|
35
38
|
iat: number;
|
|
@@ -141,6 +144,7 @@ export class M365Auth extends AuthModule {
|
|
|
141
144
|
return {
|
|
142
145
|
isAuthenticated: true,
|
|
143
146
|
userId: payload.sub,
|
|
147
|
+
email: payload.userPrincipalName || payload.email,
|
|
144
148
|
};
|
|
145
149
|
}
|
|
146
150
|
} catch {
|
|
@@ -159,6 +163,9 @@ export class M365Auth extends AuthModule {
|
|
|
159
163
|
return {
|
|
160
164
|
isAuthenticated: true,
|
|
161
165
|
userId: (payload.oid || payload.sub) as string,
|
|
166
|
+
// userPrincipalName carries the email. Use it directly if present,
|
|
167
|
+
// else the UPN-equivalent claim (preferred_username v2.0 / upn v1.0), else email.
|
|
168
|
+
email: payload.userPrincipalName || payload.preferred_username || payload.upn || payload.email,
|
|
162
169
|
};
|
|
163
170
|
} catch (err) {
|
|
164
171
|
console.error("M365 auth verification failed:", (err as Error).message);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ainetwork/adk-provider-auth-m365",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.2",
|
|
4
4
|
"author": "AI Network (https://ainetwork.ai)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"jwks-rsa": "^3.1.0"
|
|
26
26
|
},
|
|
27
27
|
"peerDependencies": {
|
|
28
|
-
"@ainetwork/adk": "^0.7.
|
|
28
|
+
"@ainetwork/adk": "^0.7.2"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
31
|
"@types/express": "^4.17.21",
|
|
@@ -36,5 +36,5 @@
|
|
|
36
36
|
"publishConfig": {
|
|
37
37
|
"access": "public"
|
|
38
38
|
},
|
|
39
|
-
"gitHead": "
|
|
39
|
+
"gitHead": "86a3b76c8d83193988b70a11abcae1f0c05aa1e9"
|
|
40
40
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../implements/m365.auth.ts"],"sourcesContent":["import { AuthModule } from \"@ainetwork/adk/modules\";\nimport { AuthResponse } from \"@ainetwork/adk/types/auth\";\nimport type { Request } from \"express\";\nimport jwt, { JwtHeader, SigningKeyCallback } from \"jsonwebtoken\";\nimport jwksClient from \"jwks-rsa\";\n\nexport interface M365AuthConfig {\n clientId: string;\n tenantId: string;\n cloudInstance?: string;\n nextAuthSecret?: string;\n}\n\ninterface AzureADTokenPayload {\n aud: string;\n iss: string;\n iat: number;\n nbf: number;\n exp: number;\n oid?: string;\n sub?: string;\n tid?: string;\n appid?: string;\n azp?: string;\n preferred_username?: string;\n email?: string;\n name?: string;\n}\n\ninterface NextAuthJWTPayload {\n name?: string;\n email?: string;\n picture?: string;\n sub: string;\n iat: number;\n exp: number;\n jti?: string;\n}\n\nexport class M365Auth extends AuthModule {\n private readonly jwksClient: jwksClient.JwksClient;\n private readonly cloudInstance: string;\n private readonly expectedIssuers: [string, ...string[]];\n\n constructor(private readonly config: M365AuthConfig) {\n super();\n this.cloudInstance = this.config.cloudInstance || \"https://login.microsoftonline.com\";\n // Support both v1.0 and v2.0 issuers\n this.expectedIssuers = [\n `${this.cloudInstance}/${this.config.tenantId}/v2.0`,\n `https://sts.windows.net/${this.config.tenantId}/`,\n ] as [string, ...string[]];\n\n this.jwksClient = jwksClient({\n jwksUri: `${this.cloudInstance}/${this.config.tenantId}/discovery/v2.0/keys`,\n cache: true,\n cacheMaxAge: 86400000, // 24 hours\n rateLimit: true,\n jwksRequestsPerMinute: 10,\n });\n }\n\n private getSigningKey = (header: JwtHeader, callback: SigningKeyCallback): void => {\n this.jwksClient.getSigningKey(header.kid, (err, key) => {\n if (err) {\n callback(err);\n return;\n }\n const signingKey = key?.getPublicKey();\n callback(null, signingKey);\n });\n };\n\n private verifyAzureADToken(token: string): Promise<AzureADTokenPayload> {\n return new Promise((resolve, reject) => {\n jwt.verify(\n token,\n this.getSigningKey,\n {\n algorithms: [\"RS256\"],\n issuer: this.expectedIssuers,\n },\n (err: Error | null, decoded: unknown) => {\n if (err) {\n reject(err);\n return;\n }\n\n const payload = decoded as AzureADTokenPayload;\n\n // For Access Tokens, verify appid or azp matches clientId\n // For ID Tokens, verify aud matches clientId\n const appId = payload.appid || payload.azp;\n if (payload.aud !== this.config.clientId && appId !== this.config.clientId) {\n reject(new Error(\"Token was not issued for this client\"));\n return;\n }\n\n resolve(payload);\n }\n );\n });\n }\n\n private verifyNextAuthToken(token: string): Promise<NextAuthJWTPayload> {\n return new Promise((resolve, reject) => {\n if (!this.config.nextAuthSecret) {\n reject(new Error(\"NextAuth secret is required for NextAuth token verification\"));\n return;\n }\n\n jwt.verify(\n token,\n this.config.nextAuthSecret,\n {\n algorithms: [\"HS256\"],\n },\n (err: Error | null, decoded: unknown) => {\n if (err) {\n reject(err);\n return;\n }\n resolve(decoded as NextAuthJWTPayload);\n }\n );\n });\n }\n\n public async authenticate(req: any, res: any): Promise<AuthResponse> {\n const token = this.extractBearerToken(req);\n if (!token) {\n return { isAuthenticated: false };\n }\n\n try {\n // First, try to verify as NextAuth JWT token (signed with NEXTAUTH_SECRET)\n if (this.config.nextAuthSecret) {\n try {\n const payload = await this.verifyNextAuthToken(token);\n if (payload.sub) {\n return {\n isAuthenticated: true,\n userId: payload.sub,\n };\n }\n } catch {\n // If NextAuth verification fails, try Azure AD token verification\n }\n }\n\n // Try to verify as Azure AD token\n const payload = await this.verifyAzureADToken(token);\n\n if (!payload.oid && !payload.sub) {\n console.error(\"M365 auth verification failed: Token does not contain oid or sub claim\");\n return { isAuthenticated: false };\n }\n\n return {\n isAuthenticated: true,\n userId: (payload.oid || payload.sub) as string,\n };\n } catch (err) {\n console.error(\"M365 auth verification failed:\", (err as Error).message);\n return { isAuthenticated: false };\n }\n }\n\n private extractBearerToken(req: Request): string | null {\n const authHeader = req.headers.authorization;\n if (!authHeader?.startsWith(\"Bearer \")) {\n return null;\n }\n return authHeader.substring(7);\n }\n}\n"],"mappings":"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","names":["payload"]}
|