@soapjs/soap-auth 0.4.4 → 1.0.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.
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.redirect = exports.setCookie = exports.getCookie = exports.setBearerToken = exports.extractBearerToken = void 0;
4
+ function extractBearerToken(context) {
5
+ const header = context?.req?.headers?.authorization ??
6
+ context?.request?.headers?.authorization ??
7
+ context?.headers?.authorization;
8
+ if (typeof header === "string" && header.toLowerCase().startsWith("bearer ")) {
9
+ return header.slice(7);
10
+ }
11
+ return undefined;
12
+ }
13
+ exports.extractBearerToken = extractBearerToken;
14
+ function setBearerToken(context, token) {
15
+ const value = `Bearer ${token}`;
16
+ if (typeof context?.res?.setHeader === "function") {
17
+ context.res.setHeader("Authorization", value);
18
+ }
19
+ else if (typeof context?.response?.setHeader === "function") {
20
+ context.response.setHeader("Authorization", value);
21
+ }
22
+ else if (typeof context?.setHeader === "function") {
23
+ context.setHeader("Authorization", value);
24
+ }
25
+ }
26
+ exports.setBearerToken = setBearerToken;
27
+ function getCookie(context, name) {
28
+ return (context?.req?.cookies?.[name] ??
29
+ context?.request?.cookies?.[name] ??
30
+ context?.cookies?.[name]);
31
+ }
32
+ exports.getCookie = getCookie;
33
+ function setCookie(context, name, value, options = {}) {
34
+ if (typeof context?.res?.cookie === "function") {
35
+ context.res.cookie(name, value, options);
36
+ }
37
+ else if (typeof context?.response?.cookie === "function") {
38
+ context.response.cookie(name, value, options);
39
+ }
40
+ else if (typeof context?.cookie === "function") {
41
+ context.cookie(name, value, options);
42
+ }
43
+ }
44
+ exports.setCookie = setCookie;
45
+ function redirect(context, url, status = 302) {
46
+ if (typeof context?.res?.redirect === "function") {
47
+ context.res.redirect(url);
48
+ }
49
+ else if (typeof context?.response?.redirect === "function") {
50
+ context.response.redirect(url);
51
+ }
52
+ else if (typeof context?.redirect === "function") {
53
+ context.redirect(url);
54
+ }
55
+ else if (typeof context?.res?.setHeader === "function") {
56
+ context.res.setHeader("Location", url);
57
+ context.res.status?.(status);
58
+ }
59
+ else if (typeof context?.setHeader === "function") {
60
+ context.setHeader("Location", url);
61
+ context.status?.(status);
62
+ }
63
+ }
64
+ exports.redirect = redirect;
@@ -0,0 +1,3 @@
1
+ export * from "./auth-config.recipes";
2
+ export * from "./http-context.helpers";
3
+ export * from "./oauth2-presets";
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./auth-config.recipes"), exports);
18
+ __exportStar(require("./http-context.helpers"), exports);
19
+ __exportStar(require("./oauth2-presets"), exports);
@@ -0,0 +1,20 @@
1
+ import { OAuth2Endpoints } from "../strategies/oauth2/oauth2.types";
2
+ export type OAuth2ProviderPreset = "auth0" | "keycloak" | "discord" | "google" | "github" | "facebook";
3
+ export interface Auth0PresetOptions {
4
+ domain: string;
5
+ }
6
+ export interface KeycloakPresetOptions {
7
+ baseUrl: string;
8
+ realm: string;
9
+ }
10
+ export interface FacebookPresetOptions {
11
+ version?: string;
12
+ }
13
+ export declare const oauth2ProviderEndpoints: {
14
+ auth0(options: Auth0PresetOptions): OAuth2Endpoints;
15
+ keycloak(options: KeycloakPresetOptions): OAuth2Endpoints;
16
+ discord(): OAuth2Endpoints;
17
+ google(): OAuth2Endpoints;
18
+ github(): OAuth2Endpoints;
19
+ facebook(options?: FacebookPresetOptions): OAuth2Endpoints;
20
+ };
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.oauth2ProviderEndpoints = void 0;
4
+ function trimTrailingSlash(value) {
5
+ return value.replace(/\/+$/, "");
6
+ }
7
+ function ensureHttpsUrl(value) {
8
+ if (/^https?:\/\//i.test(value)) {
9
+ return trimTrailingSlash(value);
10
+ }
11
+ return `https://${trimTrailingSlash(value)}`;
12
+ }
13
+ exports.oauth2ProviderEndpoints = {
14
+ auth0(options) {
15
+ if (!options?.domain) {
16
+ throw new Error("Auth0 OAuth2 preset requires domain.");
17
+ }
18
+ const baseUrl = ensureHttpsUrl(options.domain);
19
+ return {
20
+ authorizationUrl: `${baseUrl}/authorize`,
21
+ tokenUrl: `${baseUrl}/oauth/token`,
22
+ userInfoUrl: `${baseUrl}/userinfo`,
23
+ revocationUrl: `${baseUrl}/oauth/revoke`,
24
+ logoutUrl: `${baseUrl}/v2/logout`,
25
+ };
26
+ },
27
+ keycloak(options) {
28
+ if (!options?.baseUrl || !options?.realm) {
29
+ throw new Error("Keycloak OAuth2 preset requires baseUrl and realm.");
30
+ }
31
+ const baseUrl = ensureHttpsUrl(options.baseUrl);
32
+ const realmUrl = `${baseUrl}/realms/${encodeURIComponent(options.realm)}`;
33
+ return {
34
+ authorizationUrl: `${realmUrl}/protocol/openid-connect/auth`,
35
+ tokenUrl: `${realmUrl}/protocol/openid-connect/token`,
36
+ userInfoUrl: `${realmUrl}/protocol/openid-connect/userinfo`,
37
+ revocationUrl: `${realmUrl}/protocol/openid-connect/revoke`,
38
+ logoutUrl: `${realmUrl}/protocol/openid-connect/logout`,
39
+ };
40
+ },
41
+ discord() {
42
+ return {
43
+ authorizationUrl: "https://discord.com/oauth2/authorize",
44
+ tokenUrl: "https://discord.com/api/oauth2/token",
45
+ userInfoUrl: "https://discord.com/api/users/@me",
46
+ revocationUrl: "https://discord.com/api/oauth2/token/revoke",
47
+ };
48
+ },
49
+ google() {
50
+ return {
51
+ authorizationUrl: "https://accounts.google.com/o/oauth2/v2/auth",
52
+ tokenUrl: "https://oauth2.googleapis.com/token",
53
+ userInfoUrl: "https://openidconnect.googleapis.com/v1/userinfo",
54
+ revocationUrl: "https://oauth2.googleapis.com/revoke",
55
+ };
56
+ },
57
+ github() {
58
+ return {
59
+ authorizationUrl: "https://github.com/login/oauth/authorize",
60
+ tokenUrl: "https://github.com/login/oauth/access_token",
61
+ userInfoUrl: "https://api.github.com/user",
62
+ revocationUrl: "https://api.github.com/applications/{client_id}/token",
63
+ };
64
+ },
65
+ facebook(options = {}) {
66
+ const version = options.version ?? "v19.0";
67
+ return {
68
+ authorizationUrl: "https://www.facebook.com/dialog/oauth",
69
+ tokenUrl: `https://graph.facebook.com/${version}/oauth/access_token`,
70
+ userInfoUrl: `https://graph.facebook.com/${version}/me`,
71
+ revocationUrl: `https://graph.facebook.com/${version}/me/permissions`,
72
+ };
73
+ },
74
+ };
@@ -7,6 +7,7 @@ const jwt_strategy_1 = require("./strategies/jwt/jwt.strategy");
7
7
  const local_strategy_1 = require("./strategies/local/local.strategy");
8
8
  const basic_strategy_1 = require("./strategies/basic/basic.strategy");
9
9
  const api_key_strategy_1 = require("./strategies/api-key/api-key.strategy");
10
+ const providers_1 = require("./strategies/oauth2/providers");
10
11
  class SoapAuth {
11
12
  requiredStrategyMethods = ["authenticate"];
12
13
  strategies = new Map();
@@ -219,6 +220,67 @@ class SoapAuth {
219
220
  if (sharedJwt) {
220
221
  auth.addStrategy(sharedJwt, "jwt", "http");
221
222
  }
223
+ if (config.http.oauth2) {
224
+ for (const [provider, providerConfig] of Object.entries(config.http.oauth2)) {
225
+ switch (provider) {
226
+ case "google":
227
+ auth.addStrategy(new providers_1.GoogleStrategy(providerConfig, sessionHandler, sharedJwt, logger), "google", "http");
228
+ break;
229
+ case "github":
230
+ auth.addStrategy(new providers_1.GitHubStrategy(providerConfig, sessionHandler, sharedJwt, logger), "github", "http");
231
+ break;
232
+ case "facebook":
233
+ auth.addStrategy(new providers_1.FacebookStrategy(providerConfig, sessionHandler, sharedJwt, logger), "facebook", "http");
234
+ break;
235
+ default:
236
+ if (providerConfig.endpoints?.authorizationUrl &&
237
+ providerConfig.endpoints?.tokenUrl) {
238
+ auth.addStrategy(new providers_1.ConfigurableOAuth2Strategy({
239
+ ...providerConfig,
240
+ name: provider,
241
+ grantType: providerConfig.grantType ?? "authorization_code",
242
+ routes: {
243
+ login: {
244
+ path: `/auth/${provider}`,
245
+ method: "GET",
246
+ },
247
+ callback: {
248
+ path: `/auth/${provider}/callback`,
249
+ method: "GET",
250
+ },
251
+ ...providerConfig.routes,
252
+ },
253
+ }, sessionHandler, sharedJwt, logger), provider, "http");
254
+ break;
255
+ }
256
+ throw new Error(`OAuth2 provider "${provider}" requires endpoints.authorizationUrl and endpoints.tokenUrl, or a custom strategy via http.custom.`);
257
+ }
258
+ }
259
+ }
260
+ if (config.http.hybridOAuth2) {
261
+ for (const [provider, providerConfig] of Object.entries(config.http.hybridOAuth2)) {
262
+ if (!providerConfig.endpoints?.authorizationUrl ||
263
+ !providerConfig.endpoints?.tokenUrl) {
264
+ throw new Error(`Hybrid OAuth2 provider "${provider}" requires endpoints.authorizationUrl and endpoints.tokenUrl, or a custom strategy via http.custom.`);
265
+ }
266
+ auth.addStrategy(new providers_1.ConfigurableHybridOAuth2Strategy({
267
+ ...providerConfig,
268
+ name: provider,
269
+ grantType: providerConfig.grantType ?? "authorization_code",
270
+ routes: {
271
+ login: {
272
+ path: `/auth/${provider}`,
273
+ method: "GET",
274
+ },
275
+ callback: {
276
+ path: `/auth/${provider}/callback`,
277
+ method: "GET",
278
+ },
279
+ ...providerConfig.routes,
280
+ },
281
+ }, sessionHandler, sharedJwt, logger), provider, "http");
282
+ }
283
+ }
222
284
  if (config.http.custom) {
223
285
  for (const [name, strategy] of Object.entries(config.http.custom)) {
224
286
  auth.addStrategy(strategy, name, "http");
@@ -49,7 +49,7 @@ class HybridOAuth2Strategy extends oauth2_strategy_1.OAuth2Strategy {
49
49
  if (!accessToken) {
50
50
  const code = this.extractAuthorizationCode(context);
51
51
  if (!code) {
52
- this.login(context);
52
+ await this.login(context);
53
53
  throw new errors_1.MissingAuthorizationCodeError();
54
54
  }
55
55
  await this.validateState(context);
@@ -202,7 +202,7 @@ class OAuth2Strategy extends base_auth_strategy_1.BaseAuthStrategy {
202
202
  let authorizationUrl = `${this.config.endpoints.authorizationUrl}?${params.toString()}`;
203
203
  if (this.pkce) {
204
204
  const codeVerifier = await this.pkce.generateCodeVerifier(context);
205
- const codeChallenge = this.pkce.generateCodeChallenge(codeVerifier, context);
205
+ const codeChallenge = await this.pkce.generateCodeChallenge(codeVerifier, context);
206
206
  authorizationUrl += `&code_challenge=${codeChallenge}&code_challenge_method=S256`;
207
207
  }
208
208
  return authorizationUrl;
@@ -212,7 +212,7 @@ class OAuth2Strategy extends base_auth_strategy_1.BaseAuthStrategy {
212
212
  grant_type: "authorization_code",
213
213
  client_id: this.config.clientId,
214
214
  code,
215
- redirectUri: this.config.redirectUri,
215
+ redirect_uri: this.config.redirectUri,
216
216
  };
217
217
  if (this.pkce) {
218
218
  const codeVerifier = this.pkce.extractCodeVerifier(context);
@@ -50,3 +50,8 @@ export interface OAuth2StrategyConfig<TContext = unknown, TUser = unknown> exten
50
50
  nonce?: OAuth2NonceConfig;
51
51
  jwks?: JwksConfig;
52
52
  }
53
+ export interface OAuth2ProviderConfig<TContext = unknown, TUser = unknown> extends Omit<OAuth2StrategyConfig<TContext, TUser>, "endpoints" | "grantType" | "routes"> {
54
+ grantType?: "authorization_code";
55
+ endpoints?: Partial<OAuth2Endpoints>;
56
+ routes?: OAuth2StrategyConfig<TContext, TUser>["routes"];
57
+ }
@@ -0,0 +1,19 @@
1
+ import * as Soap from "@soapjs/soap";
2
+ import { SessionHandler } from "../../../session/session-handler";
3
+ import { JwtStrategy } from "../../jwt/jwt.strategy";
4
+ import { HybridOAuth2Strategy } from "../hybrid.oauth2.strategy";
5
+ import { ConfigurableOAuth2StrategyConfig } from "./provider.types";
6
+ export declare class ConfigurableHybridOAuth2Strategy<TUser extends Soap.AuthUser = Soap.AuthUser> extends HybridOAuth2Strategy<Soap.HttpContext, TUser> {
7
+ protected config: ConfigurableOAuth2StrategyConfig<TUser>;
8
+ readonly name: string;
9
+ constructor(config: ConfigurableOAuth2StrategyConfig<TUser>, session?: SessionHandler, jwt?: JwtStrategy<Soap.HttpContext, TUser>, logger?: Soap.Logger);
10
+ protected extractAccessToken(ctx: Soap.HttpContext): Promise<string | undefined>;
11
+ protected extractRefreshToken(ctx: Soap.HttpContext): Promise<string | undefined>;
12
+ protected storeAccessToken(_token: string, _ctx: Soap.HttpContext): Promise<void>;
13
+ protected storeRefreshToken(_token: string, _ctx: Soap.HttpContext): Promise<void>;
14
+ protected embedAccessToken(token: string, ctx: Soap.HttpContext): void;
15
+ protected embedRefreshToken(token: string, ctx: Soap.HttpContext): void;
16
+ protected extractAuthorizationCode(ctx: Soap.HttpContext): string | null;
17
+ protected redirectUser(ctx: Soap.HttpContext, authUrl: string): void;
18
+ protected fetchUser(accessToken: string): Promise<TUser | null>;
19
+ }
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ConfigurableHybridOAuth2Strategy = void 0;
4
+ const errors_1 = require("../../../errors");
5
+ const hybrid_oauth2_strategy_1 = require("../hybrid.oauth2.strategy");
6
+ class ConfigurableHybridOAuth2Strategy extends hybrid_oauth2_strategy_1.HybridOAuth2Strategy {
7
+ config;
8
+ name;
9
+ constructor(config, session, jwt, logger) {
10
+ super(config, session, jwt, logger);
11
+ this.config = config;
12
+ this.name = config.name;
13
+ }
14
+ extractAccessToken(ctx) {
15
+ const auth = ctx.req.headers?.authorization;
16
+ if (typeof auth === "string" && auth.startsWith("Bearer ")) {
17
+ return Promise.resolve(auth.slice(7));
18
+ }
19
+ return Promise.resolve(ctx.req.cookies?.access_token);
20
+ }
21
+ extractRefreshToken(ctx) {
22
+ return Promise.resolve(ctx.req.cookies?.refresh_token);
23
+ }
24
+ storeAccessToken(_token, _ctx) {
25
+ return Promise.resolve();
26
+ }
27
+ storeRefreshToken(_token, _ctx) {
28
+ return Promise.resolve();
29
+ }
30
+ embedAccessToken(token, ctx) {
31
+ ctx.res.setHeader("Authorization", `Bearer ${token}`);
32
+ }
33
+ embedRefreshToken(token, ctx) {
34
+ ctx.res.cookie("refresh_token", token, {
35
+ httpOnly: true,
36
+ secure: true,
37
+ sameSite: "lax",
38
+ maxAge: 30 * 24 * 60 * 60 * 1000,
39
+ });
40
+ }
41
+ extractAuthorizationCode(ctx) {
42
+ return ctx.req.query?.code ?? null;
43
+ }
44
+ redirectUser(ctx, authUrl) {
45
+ if (typeof ctx.res.redirect === "function") {
46
+ ctx.res.redirect(authUrl);
47
+ }
48
+ else {
49
+ ctx.res.setHeader("Location", authUrl);
50
+ ctx.res.status(302).json({ message: "Redirecting", location: authUrl });
51
+ }
52
+ }
53
+ async fetchUser(accessToken) {
54
+ try {
55
+ if (!this.config.endpoints.userInfoUrl) {
56
+ if (this.config.user?.fetchUser) {
57
+ return this.config.user.fetchUser(accessToken);
58
+ }
59
+ throw new errors_1.MissingConfigError("userInfoUrl");
60
+ }
61
+ const response = await fetch(this.config.endpoints.userInfoUrl, {
62
+ headers: { Authorization: `Bearer ${accessToken}` },
63
+ });
64
+ if (!response.ok) {
65
+ return null;
66
+ }
67
+ const profile = await response.json();
68
+ if (this.config.user?.validateUser) {
69
+ return this.config.user.validateUser(profile);
70
+ }
71
+ return {
72
+ id: profile.sub ?? profile.id,
73
+ email: profile.email,
74
+ username: profile.preferred_username ?? profile.username ?? profile.name,
75
+ name: profile.name,
76
+ picture: profile.picture ?? profile.avatar_url,
77
+ };
78
+ }
79
+ catch (error) {
80
+ this.logger?.error("ConfigurableHybridOAuth2Strategy.fetchUser failed:", error);
81
+ return null;
82
+ }
83
+ }
84
+ }
85
+ exports.ConfigurableHybridOAuth2Strategy = ConfigurableHybridOAuth2Strategy;
@@ -0,0 +1,11 @@
1
+ import * as Soap from "@soapjs/soap";
2
+ import { SessionHandler } from "../../../session/session-handler";
3
+ import { JwtStrategy } from "../../jwt/jwt.strategy";
4
+ import { HttpOAuth2Strategy } from "./http-oauth2.strategy";
5
+ import { ConfigurableOAuth2StrategyConfig } from "./provider.types";
6
+ export declare class ConfigurableOAuth2Strategy<TUser extends Soap.AuthUser = Soap.AuthUser> extends HttpOAuth2Strategy<TUser> {
7
+ protected config: ConfigurableOAuth2StrategyConfig<TUser>;
8
+ readonly name: string;
9
+ constructor(config: ConfigurableOAuth2StrategyConfig<TUser>, session?: SessionHandler, jwt?: JwtStrategy<Soap.HttpContext, TUser>, logger?: Soap.Logger);
10
+ protected fetchUser(accessToken: string): Promise<TUser | null>;
11
+ }
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ConfigurableOAuth2Strategy = void 0;
4
+ const http_oauth2_strategy_1 = require("./http-oauth2.strategy");
5
+ const errors_1 = require("../../../errors");
6
+ class ConfigurableOAuth2Strategy extends http_oauth2_strategy_1.HttpOAuth2Strategy {
7
+ config;
8
+ name;
9
+ constructor(config, session, jwt, logger) {
10
+ super(config, session, jwt, logger);
11
+ this.config = config;
12
+ this.name = config.name;
13
+ }
14
+ async fetchUser(accessToken) {
15
+ try {
16
+ if (!this.config.endpoints.userInfoUrl) {
17
+ if (this.config.user?.fetchUser) {
18
+ return this.config.user.fetchUser(accessToken);
19
+ }
20
+ throw new errors_1.MissingConfigError("userInfoUrl");
21
+ }
22
+ const response = await fetch(this.config.endpoints.userInfoUrl, {
23
+ headers: { Authorization: `Bearer ${accessToken}` },
24
+ });
25
+ if (!response.ok) {
26
+ return null;
27
+ }
28
+ const profile = await response.json();
29
+ if (this.config.user?.validateUser) {
30
+ return this.config.user.validateUser(profile);
31
+ }
32
+ return {
33
+ id: profile.sub ?? profile.id,
34
+ email: profile.email,
35
+ username: profile.preferred_username ?? profile.username ?? profile.name,
36
+ name: profile.name,
37
+ picture: profile.picture ?? profile.avatar_url,
38
+ };
39
+ }
40
+ catch (error) {
41
+ this.logger?.error("ConfigurableOAuth2Strategy.fetchUser failed:", error);
42
+ return null;
43
+ }
44
+ }
45
+ }
46
+ exports.ConfigurableOAuth2Strategy = ConfigurableOAuth2Strategy;
@@ -1,4 +1,6 @@
1
1
  export * from "./http-oauth2.strategy";
2
+ export * from "./configurable-oauth2.strategy";
3
+ export * from "./configurable-hybrid-oauth2.strategy";
2
4
  export * from "./google.strategy";
3
5
  export * from "./github.strategy";
4
6
  export * from "./facebook.strategy";
@@ -15,6 +15,8 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./http-oauth2.strategy"), exports);
18
+ __exportStar(require("./configurable-oauth2.strategy"), exports);
19
+ __exportStar(require("./configurable-hybrid-oauth2.strategy"), exports);
18
20
  __exportStar(require("./google.strategy"), exports);
19
21
  __exportStar(require("./github.strategy"), exports);
20
22
  __exportStar(require("./facebook.strategy"), exports);
@@ -5,3 +5,6 @@ export interface SocialProviderConfig<TUser extends Soap.AuthUser = Soap.AuthUse
5
5
  endpoints?: Partial<OAuth2Endpoints>;
6
6
  routes?: OAuth2StrategyConfig<Soap.HttpContext, TUser>["routes"];
7
7
  }
8
+ export interface ConfigurableOAuth2StrategyConfig<TUser extends Soap.AuthUser = Soap.AuthUser> extends OAuth2StrategyConfig<Soap.HttpContext, TUser> {
9
+ name: string;
10
+ }
package/build/types.d.ts CHANGED
@@ -2,7 +2,7 @@ import * as Soap from "@soapjs/soap";
2
2
  export type AuthResult<TUser extends Soap.AuthUser = Soap.AuthUser> = Soap.AuthResult<TUser>;
3
3
  export type AuthStrategy<TUser extends Soap.AuthUser = Soap.AuthUser> = Soap.AuthStrategy<TUser>;
4
4
  import { LocalStrategyConfig } from "./strategies/local/local.types";
5
- import { OAuth2StrategyConfig } from "./strategies/oauth2/oauth2.types";
5
+ import { OAuth2ProviderConfig } from "./strategies/oauth2/oauth2.types";
6
6
  import { ApiKeyStrategyConfig } from "./strategies/api-key/api-key.types";
7
7
  import { BasicStrategyConfig } from "./strategies/basic/basic.types";
8
8
  import { JwtConfig } from "./strategies/jwt/jwt.types";
@@ -175,7 +175,10 @@ export interface SoapHttpAuthConfig<TContext = unknown, TUser extends Soap.AuthU
175
175
  local?: LocalStrategyConfig<TContext, TUser>;
176
176
  jwt?: JwtConfig<TContext, TUser>;
177
177
  oauth2?: {
178
- [provider: string]: OAuth2StrategyConfig<TContext, TUser>;
178
+ [provider: string]: OAuth2ProviderConfig<TContext, TUser>;
179
+ };
180
+ hybridOAuth2?: {
181
+ [provider: string]: OAuth2ProviderConfig<TContext, TUser>;
179
182
  };
180
183
  apiKey?: ApiKeyStrategyConfig<TContext, TUser>;
181
184
  basic?: BasicStrategyConfig<TContext, TUser>;
package/package.json CHANGED
@@ -1,35 +1,113 @@
1
1
  {
2
2
  "name": "@soapjs/soap-auth",
3
- "version": "0.4.4",
4
- "description": "",
3
+ "version": "1.0.0",
4
+ "description": "Authentication strategies, sessions, MFA, and token helpers for the SoapJS ecosystem.",
5
5
  "homepage": "https://docs.soapjs.com",
6
- "repository": "https://github.com/soapjs/soap-auth",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/soapjs/soap-auth.git"
9
+ },
7
10
  "main": "build/index.js",
8
11
  "types": "build/index.d.ts",
12
+ "exports": {
13
+ ".": {
14
+ "types": "./build/index.d.ts",
15
+ "require": "./build/index.js"
16
+ },
17
+ "./session": {
18
+ "types": "./build/session/index.d.ts",
19
+ "require": "./build/session/index.js"
20
+ },
21
+ "./session/*": {
22
+ "types": "./build/session/*.d.ts",
23
+ "require": "./build/session/*.js"
24
+ },
25
+ "./services": {
26
+ "types": "./build/services/index.d.ts",
27
+ "require": "./build/services/index.js"
28
+ },
29
+ "./services/*": {
30
+ "types": "./build/services/*.d.ts",
31
+ "require": "./build/services/*.js"
32
+ },
33
+ "./strategies": {
34
+ "types": "./build/strategies/index.d.ts",
35
+ "require": "./build/strategies/index.js"
36
+ },
37
+ "./strategies/*": {
38
+ "types": "./build/strategies/*.d.ts",
39
+ "require": "./build/strategies/*.js"
40
+ },
41
+ "./tools": {
42
+ "types": "./build/tools/index.d.ts",
43
+ "require": "./build/tools/index.js"
44
+ },
45
+ "./tools/*": {
46
+ "types": "./build/tools/*.d.ts",
47
+ "require": "./build/tools/*.js"
48
+ },
49
+ "./recipes": {
50
+ "types": "./build/recipes/index.d.ts",
51
+ "require": "./build/recipes/index.js"
52
+ },
53
+ "./recipes/*": {
54
+ "types": "./build/recipes/*.d.ts",
55
+ "require": "./build/recipes/*.js"
56
+ },
57
+ "./errors": {
58
+ "types": "./build/errors.d.ts",
59
+ "require": "./build/errors.js"
60
+ },
61
+ "./types": {
62
+ "types": "./build/types.d.ts",
63
+ "require": "./build/types.js"
64
+ },
65
+ "./soap-auth": {
66
+ "types": "./build/soap-auth.d.ts",
67
+ "require": "./build/soap-auth.js"
68
+ },
69
+ "./utils/validation": {
70
+ "types": "./build/utils/validation.d.ts",
71
+ "require": "./build/utils/validation.js"
72
+ },
73
+ "./package.json": "./package.json"
74
+ },
75
+ "files": [
76
+ "build",
77
+ "README.md",
78
+ "LICENSE",
79
+ "ldap.md",
80
+ "saml.md"
81
+ ],
82
+ "sideEffects": false,
9
83
  "license": "MIT",
10
84
  "author": "Radoslaw Kamysz",
11
85
  "scripts": {
12
86
  "test:unit": "jest --config=jest.config.unit.json",
13
87
  "clean": "rm -rf ./build",
14
- "build": "npm run clean && tsc -b",
15
- "prepublish": "npm run clean && tsc --project tsconfig.build.json"
88
+ "build": "npm run clean && tsc --project tsconfig.build.json",
89
+ "prepack": "npm run build",
90
+ "prepublishOnly": "npm run test:unit && npm run build"
91
+ },
92
+ "publishConfig": {
93
+ "access": "public"
16
94
  },
17
95
  "devDependencies": {
18
- "@soapjs/soap": "^0.12.0",
19
- "@types/jest": "^27.0.3",
20
- "jest": "^27.4.5",
21
- "ts-jest": "^27.1.3",
96
+ "@soapjs/soap": "^0.12.1",
97
+ "@types/jest": "^29.5.14",
98
+ "jest": "^29.7.0",
99
+ "ts-jest": "^29.4.11",
22
100
  "typescript": "^4.8.2"
23
101
  },
24
102
  "peerDependencies": {
25
103
  "@soapjs/soap": ">=0.12.0"
26
104
  },
27
105
  "engines": {
28
- "node": ">=18.0.0"
106
+ "node": ">=24.17.0"
29
107
  },
30
108
  "dependencies": {
31
109
  "bcrypt": "^6.0.0",
32
- "jsonwebtoken": "^9.0.2",
33
- "jwks-rsa": "^3.1.0"
110
+ "jsonwebtoken": "^9.0.3",
111
+ "jwks-rsa": "^3.2.2"
34
112
  }
35
113
  }