@vunexa/lixa 0.1.6-alpha.13 → 0.1.6-alpha.14
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/README.md +101 -687
- package/dist/credentials/types.d.ts +6 -6
- package/dist/credentials/types.d.ts.map +1 -1
- package/dist/dao/session-cache.d.ts.map +1 -1
- package/dist/dao/types.d.ts +19 -0
- package/dist/dao/types.d.ts.map +1 -1
- package/dist/errors.d.ts +19 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/export-types/index.d.ts +556 -41
- package/dist/identity/index.d.ts +3 -0
- package/dist/identity/index.d.ts.map +1 -0
- package/dist/identity/self-managed.d.ts +52 -0
- package/dist/identity/self-managed.d.ts.map +1 -0
- package/dist/identity/types.d.ts +224 -0
- package/dist/identity/types.d.ts.map +1 -0
- package/dist/index.cjs +658 -213
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +563 -65
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +654 -213
- package/dist/index.js.map +1 -1
- package/dist/lixa.d.ts +123 -28
- package/dist/lixa.d.ts.map +1 -1
- package/dist/models/session.d.ts +2 -2
- package/dist/models/session.d.ts.map +1 -1
- package/dist/providers/IProvider.d.ts +4 -0
- package/dist/providers/IProvider.d.ts.map +1 -1
- package/dist/types.d.ts +82 -5
- package/dist/types.d.ts.map +1 -1
- package/package.json +3 -11
package/dist/index.cjs
CHANGED
|
@@ -39,6 +39,8 @@ __export(src_exports, {
|
|
|
39
39
|
DEFAULT_STATE_COOKIE_NAME: () => DEFAULT_STATE_COOKIE_NAME,
|
|
40
40
|
DEFAULT_STATE_MAX_AGE_SECONDS: () => DEFAULT_STATE_MAX_AGE_SECONDS,
|
|
41
41
|
EmailNotVerifiedError: () => EmailNotVerifiedError,
|
|
42
|
+
IdentityNotConfiguredError: () => IdentityNotConfiguredError,
|
|
43
|
+
IdentityProviderError: () => IdentityProviderError,
|
|
42
44
|
InvalidCredentialsError: () => InvalidCredentialsError,
|
|
43
45
|
InvalidOAuthCallbackError: () => InvalidOAuthCallbackError,
|
|
44
46
|
InvalidProviderConfigError: () => InvalidProviderConfigError,
|
|
@@ -50,6 +52,7 @@ __export(src_exports, {
|
|
|
50
52
|
ProviderNotConfiguredError: () => ProviderNotConfiguredError,
|
|
51
53
|
RefreshTokenError: () => RefreshTokenError,
|
|
52
54
|
ScryptPasswordHasher: () => ScryptPasswordHasher,
|
|
55
|
+
SelfManagedIdentityProvider: () => SelfManagedIdentityProvider,
|
|
53
56
|
SessionNotFoundError: () => SessionNotFoundError,
|
|
54
57
|
TokenExchangeError: () => TokenExchangeError,
|
|
55
58
|
UserAlreadyExistsError: () => UserAlreadyExistsError,
|
|
@@ -64,6 +67,7 @@ __export(src_exports, {
|
|
|
64
67
|
determineProviderFromIssuer: () => determineProviderFromIssuer,
|
|
65
68
|
extractUserInfo: () => extractUserInfo,
|
|
66
69
|
fetchUserInfo: () => fetchUserInfo,
|
|
70
|
+
identity: () => identity_exports,
|
|
67
71
|
isProductionEnvironment: () => isProductionEnvironment,
|
|
68
72
|
serializeCookie: () => serializeCookie,
|
|
69
73
|
validatePasswordPolicy: () => validatePasswordPolicy
|
|
@@ -453,10 +457,24 @@ var WeakPasswordError = class extends LixaError {
|
|
|
453
457
|
}
|
|
454
458
|
};
|
|
455
459
|
var CredentialsNotConfiguredError = class extends LixaError {
|
|
456
|
-
constructor(message = "Credentials authentication is not configured in this Lixa instance. Pass credentials: {} in LixaConfig to enable it.", details) {
|
|
460
|
+
constructor(message = "Credentials authentication is not configured in this Lixa instance. Pass credentials: {} or identity: ... in LixaConfig to enable it.", details) {
|
|
457
461
|
super(message, "CREDENTIALS_NOT_CONFIGURED", details);
|
|
458
462
|
}
|
|
459
463
|
};
|
|
464
|
+
var IdentityProviderError = class extends LixaError {
|
|
465
|
+
provider;
|
|
466
|
+
statusCode;
|
|
467
|
+
constructor(message, provider, statusCode, details) {
|
|
468
|
+
super(message, "IDENTITY_PROVIDER_ERROR", { provider, statusCode, ...details });
|
|
469
|
+
this.provider = provider;
|
|
470
|
+
this.statusCode = statusCode;
|
|
471
|
+
}
|
|
472
|
+
};
|
|
473
|
+
var IdentityNotConfiguredError = class extends CredentialsNotConfiguredError {
|
|
474
|
+
constructor(message = "Identity provider is not configured in this Lixa instance. Pass identity: ... or credentials: {} in LixaConfig to enable it.", details) {
|
|
475
|
+
super(message, details);
|
|
476
|
+
}
|
|
477
|
+
};
|
|
460
478
|
|
|
461
479
|
// src/credentials/credentials-manager.ts
|
|
462
480
|
var CredentialsManager = class {
|
|
@@ -652,6 +670,94 @@ var CredentialsManager = class {
|
|
|
652
670
|
}
|
|
653
671
|
};
|
|
654
672
|
|
|
673
|
+
// src/identity/self-managed.ts
|
|
674
|
+
var SelfManagedIdentityProvider = class {
|
|
675
|
+
name = "self-managed";
|
|
676
|
+
manager;
|
|
677
|
+
constructor(configOrManager) {
|
|
678
|
+
if (configOrManager instanceof CredentialsManager) {
|
|
679
|
+
this.manager = configOrManager;
|
|
680
|
+
} else {
|
|
681
|
+
this.manager = new CredentialsManager(configOrManager || {});
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
mapUser(user) {
|
|
685
|
+
return {
|
|
686
|
+
id: user.id,
|
|
687
|
+
identifier: user.identifier,
|
|
688
|
+
username: user.username,
|
|
689
|
+
email: user.email,
|
|
690
|
+
emailVerified: true,
|
|
691
|
+
// Self-managed accounts verify locally unless configured otherwise
|
|
692
|
+
createdAt: user.createdAt,
|
|
693
|
+
updatedAt: user.updatedAt,
|
|
694
|
+
metadata: user.metadata,
|
|
695
|
+
provider: this.name
|
|
696
|
+
};
|
|
697
|
+
}
|
|
698
|
+
/**
|
|
699
|
+
* Registers a new user.
|
|
700
|
+
*/
|
|
701
|
+
async signUp(params) {
|
|
702
|
+
const user = await this.manager.signUp(params);
|
|
703
|
+
return this.mapUser(user);
|
|
704
|
+
}
|
|
705
|
+
/**
|
|
706
|
+
* Authenticates a user with password.
|
|
707
|
+
*/
|
|
708
|
+
async signIn(params) {
|
|
709
|
+
const user = await this.manager.verifyCredentials(params);
|
|
710
|
+
if (!user) {
|
|
711
|
+
throw new InvalidCredentialsError();
|
|
712
|
+
}
|
|
713
|
+
return {
|
|
714
|
+
user: this.mapUser(user)
|
|
715
|
+
};
|
|
716
|
+
}
|
|
717
|
+
/**
|
|
718
|
+
* Verifies credentials without throwing an error if invalid.
|
|
719
|
+
*/
|
|
720
|
+
async verifyCredentials(params) {
|
|
721
|
+
const user = await this.manager.verifyCredentials(params);
|
|
722
|
+
return user ? this.mapUser(user) : null;
|
|
723
|
+
}
|
|
724
|
+
/**
|
|
725
|
+
* Changes a user's password.
|
|
726
|
+
*/
|
|
727
|
+
async changePassword(params) {
|
|
728
|
+
return await this.manager.changePassword(params);
|
|
729
|
+
}
|
|
730
|
+
/**
|
|
731
|
+
* Retrieves a user by their unique ID.
|
|
732
|
+
*/
|
|
733
|
+
async getUserById(id) {
|
|
734
|
+
const user = await this.manager.getUserById(id);
|
|
735
|
+
return user ? this.mapUser(user) : null;
|
|
736
|
+
}
|
|
737
|
+
/**
|
|
738
|
+
* Retrieves a user by their identifier (email or username).
|
|
739
|
+
*/
|
|
740
|
+
async getUserByIdentifier(identifier) {
|
|
741
|
+
const user = await this.manager.getUserByIdentifier(identifier);
|
|
742
|
+
return user ? this.mapUser(user) : null;
|
|
743
|
+
}
|
|
744
|
+
/**
|
|
745
|
+
* Deletes a user from storage if supported by the storage adapter.
|
|
746
|
+
*/
|
|
747
|
+
async deleteUser(id) {
|
|
748
|
+
const storage = this.manager.getStorage();
|
|
749
|
+
if (typeof storage.deleteUser === "function") {
|
|
750
|
+
await storage.deleteUser(id);
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
/**
|
|
754
|
+
* Returns the underlying CredentialsManager instance.
|
|
755
|
+
*/
|
|
756
|
+
getCredentialsManager() {
|
|
757
|
+
return this.manager;
|
|
758
|
+
}
|
|
759
|
+
};
|
|
760
|
+
|
|
655
761
|
// src/types.ts
|
|
656
762
|
var AccountLinkingStrategy = /* @__PURE__ */ ((AccountLinkingStrategy2) => {
|
|
657
763
|
AccountLinkingStrategy2["AUTO_LINK_BY_VERIFIED_EMAIL"] = "AUTO_LINK_BY_VERIFIED_EMAIL";
|
|
@@ -757,10 +863,7 @@ var LocalSessionHandler = class {
|
|
|
757
863
|
if (!tokenData.access_token || typeof tokenData.access_token !== "string") {
|
|
758
864
|
throw new Error("No valid access token found in OAuth response");
|
|
759
865
|
}
|
|
760
|
-
const session = {
|
|
761
|
-
token: tokenData.access_token,
|
|
762
|
-
raw: tokenData
|
|
763
|
-
};
|
|
866
|
+
const session = {};
|
|
764
867
|
return session;
|
|
765
868
|
}
|
|
766
869
|
// PascalCase alias for backward compatibility
|
|
@@ -838,6 +941,125 @@ async function extractUserInfo(tokenData, providerMetadata) {
|
|
|
838
941
|
return { userInfo };
|
|
839
942
|
}
|
|
840
943
|
|
|
944
|
+
// src/utils/cookies.ts
|
|
945
|
+
var DEFAULT_SESSION_COOKIE_NAME = "lixa_session";
|
|
946
|
+
var DEFAULT_STATE_COOKIE_NAME = "lixa_oauth_state";
|
|
947
|
+
var DEFAULT_SESSION_MAX_AGE_SECONDS = 24 * 60 * 60;
|
|
948
|
+
var DEFAULT_STATE_MAX_AGE_SECONDS = 5 * 60;
|
|
949
|
+
function isProductionEnvironment() {
|
|
950
|
+
return typeof process !== "undefined" && process.env?.NODE_ENV === "production";
|
|
951
|
+
}
|
|
952
|
+
function serializeCookie(name, value, options) {
|
|
953
|
+
const isProd = isProductionEnvironment();
|
|
954
|
+
const path = options?.path ?? "/";
|
|
955
|
+
const httpOnly = options?.httpOnly ?? true;
|
|
956
|
+
const secure = options?.secure ?? isProd;
|
|
957
|
+
const sameSite = options?.sameSite ?? "lax";
|
|
958
|
+
const parts = [`${encodeURIComponent(name)}=${encodeURIComponent(value)}`];
|
|
959
|
+
if (path) {
|
|
960
|
+
parts.push(`Path=${path}`);
|
|
961
|
+
}
|
|
962
|
+
if (typeof options?.maxAge === "number") {
|
|
963
|
+
parts.push(`Max-Age=${Math.floor(options.maxAge)}`);
|
|
964
|
+
const expires = new Date(Date.now() + options.maxAge * 1e3).toUTCString();
|
|
965
|
+
parts.push(`Expires=${expires}`);
|
|
966
|
+
}
|
|
967
|
+
if (options?.domain) {
|
|
968
|
+
parts.push(`Domain=${options.domain}`);
|
|
969
|
+
}
|
|
970
|
+
if (httpOnly) {
|
|
971
|
+
parts.push("HttpOnly");
|
|
972
|
+
}
|
|
973
|
+
if (secure) {
|
|
974
|
+
parts.push("Secure");
|
|
975
|
+
}
|
|
976
|
+
if (sameSite) {
|
|
977
|
+
const capitalized = sameSite.charAt(0).toUpperCase() + sameSite.slice(1).toLowerCase();
|
|
978
|
+
parts.push(`SameSite=${capitalized}`);
|
|
979
|
+
}
|
|
980
|
+
return parts.join("; ");
|
|
981
|
+
}
|
|
982
|
+
function createSessionCookie(sessionId, options) {
|
|
983
|
+
const isProd = isProductionEnvironment();
|
|
984
|
+
const resolvedOptions = {
|
|
985
|
+
name: options?.name || DEFAULT_SESSION_COOKIE_NAME,
|
|
986
|
+
path: options?.path ?? "/",
|
|
987
|
+
maxAge: options?.maxAge ?? DEFAULT_SESSION_MAX_AGE_SECONDS,
|
|
988
|
+
httpOnly: options?.httpOnly ?? true,
|
|
989
|
+
secure: options?.secure ?? isProd,
|
|
990
|
+
sameSite: options?.sameSite ?? "lax",
|
|
991
|
+
domain: options?.domain
|
|
992
|
+
};
|
|
993
|
+
const name = resolvedOptions.name;
|
|
994
|
+
const header = serializeCookie(name, sessionId, resolvedOptions);
|
|
995
|
+
return {
|
|
996
|
+
name,
|
|
997
|
+
value: sessionId,
|
|
998
|
+
options: resolvedOptions,
|
|
999
|
+
header
|
|
1000
|
+
};
|
|
1001
|
+
}
|
|
1002
|
+
function clearSessionCookie(options) {
|
|
1003
|
+
const isProd = isProductionEnvironment();
|
|
1004
|
+
const resolvedOptions = {
|
|
1005
|
+
name: options?.name || DEFAULT_SESSION_COOKIE_NAME,
|
|
1006
|
+
path: options?.path ?? "/",
|
|
1007
|
+
maxAge: 0,
|
|
1008
|
+
httpOnly: options?.httpOnly ?? true,
|
|
1009
|
+
secure: options?.secure ?? isProd,
|
|
1010
|
+
sameSite: options?.sameSite ?? "lax",
|
|
1011
|
+
domain: options?.domain
|
|
1012
|
+
};
|
|
1013
|
+
const name = resolvedOptions.name;
|
|
1014
|
+
const header = serializeCookie(name, "", resolvedOptions);
|
|
1015
|
+
return {
|
|
1016
|
+
name,
|
|
1017
|
+
value: "",
|
|
1018
|
+
options: resolvedOptions,
|
|
1019
|
+
header
|
|
1020
|
+
};
|
|
1021
|
+
}
|
|
1022
|
+
function createStateCookie(state, options) {
|
|
1023
|
+
const isProd = isProductionEnvironment();
|
|
1024
|
+
const resolvedOptions = {
|
|
1025
|
+
name: options?.name || DEFAULT_STATE_COOKIE_NAME,
|
|
1026
|
+
path: options?.path ?? "/",
|
|
1027
|
+
maxAge: options?.maxAge ?? DEFAULT_STATE_MAX_AGE_SECONDS,
|
|
1028
|
+
httpOnly: options?.httpOnly ?? true,
|
|
1029
|
+
secure: options?.secure ?? isProd,
|
|
1030
|
+
sameSite: options?.sameSite ?? "lax",
|
|
1031
|
+
domain: options?.domain
|
|
1032
|
+
};
|
|
1033
|
+
const name = resolvedOptions.name;
|
|
1034
|
+
const header = serializeCookie(name, state, resolvedOptions);
|
|
1035
|
+
return {
|
|
1036
|
+
name,
|
|
1037
|
+
value: state,
|
|
1038
|
+
options: resolvedOptions,
|
|
1039
|
+
header
|
|
1040
|
+
};
|
|
1041
|
+
}
|
|
1042
|
+
function clearStateCookie(options) {
|
|
1043
|
+
const isProd = isProductionEnvironment();
|
|
1044
|
+
const resolvedOptions = {
|
|
1045
|
+
name: options?.name || DEFAULT_STATE_COOKIE_NAME,
|
|
1046
|
+
path: options?.path ?? "/",
|
|
1047
|
+
maxAge: 0,
|
|
1048
|
+
httpOnly: options?.httpOnly ?? true,
|
|
1049
|
+
secure: options?.secure ?? isProd,
|
|
1050
|
+
sameSite: options?.sameSite ?? "lax",
|
|
1051
|
+
domain: options?.domain
|
|
1052
|
+
};
|
|
1053
|
+
const name = resolvedOptions.name;
|
|
1054
|
+
const header = serializeCookie(name, "", resolvedOptions);
|
|
1055
|
+
return {
|
|
1056
|
+
name,
|
|
1057
|
+
value: "",
|
|
1058
|
+
options: resolvedOptions,
|
|
1059
|
+
header
|
|
1060
|
+
};
|
|
1061
|
+
}
|
|
1062
|
+
|
|
841
1063
|
// src/lixa.ts
|
|
842
1064
|
var Lixa = class _Lixa {
|
|
843
1065
|
static DEFAULT_PROVIDERS = /* @__PURE__ */ new Map();
|
|
@@ -847,14 +1069,19 @@ var Lixa = class _Lixa {
|
|
|
847
1069
|
localStateHandler;
|
|
848
1070
|
localSessionHandler;
|
|
849
1071
|
localResourceHandler;
|
|
1072
|
+
localAccountHandler;
|
|
850
1073
|
userResourceStore = /* @__PURE__ */ new Map();
|
|
1074
|
+
userAccountStore = /* @__PURE__ */ new Map();
|
|
851
1075
|
refreshMutexes = /* @__PURE__ */ new Map();
|
|
1076
|
+
identityProvider;
|
|
852
1077
|
credentialsManager;
|
|
853
1078
|
config;
|
|
854
1079
|
stateHandler;
|
|
855
1080
|
sessionHandler;
|
|
856
1081
|
resourceHandler;
|
|
1082
|
+
accountHandler;
|
|
857
1083
|
debug;
|
|
1084
|
+
sessionCookieResolver;
|
|
858
1085
|
/**
|
|
859
1086
|
* Creates a new Lixa instance with the provided configuration.
|
|
860
1087
|
*
|
|
@@ -869,7 +1096,15 @@ var Lixa = class _Lixa {
|
|
|
869
1096
|
* @throws Error when provider is not available and no inline implementation is provided
|
|
870
1097
|
*/
|
|
871
1098
|
constructor(config) {
|
|
872
|
-
this.
|
|
1099
|
+
this.sessionCookieResolver = config.sessionCookieName;
|
|
1100
|
+
const federatedOAuthProviders = config.federatedOAuthProviders || config.providers;
|
|
1101
|
+
this.config = {
|
|
1102
|
+
...config,
|
|
1103
|
+
...federatedOAuthProviders ? {
|
|
1104
|
+
providers: federatedOAuthProviders,
|
|
1105
|
+
federatedOAuthProviders
|
|
1106
|
+
} : {}
|
|
1107
|
+
};
|
|
873
1108
|
this.debug = config.debug || false;
|
|
874
1109
|
this.localStateHandler = new LocalStateHandler();
|
|
875
1110
|
this.localSessionHandler = new LocalSessionHandler();
|
|
@@ -905,19 +1140,70 @@ var Lixa = class _Lixa {
|
|
|
905
1140
|
}
|
|
906
1141
|
}
|
|
907
1142
|
};
|
|
908
|
-
this.
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
1143
|
+
this.localAccountHandler = {
|
|
1144
|
+
accountStorage: {
|
|
1145
|
+
saveAccount: async (userId, provider, account) => {
|
|
1146
|
+
let userMap = this.userAccountStore.get(userId);
|
|
1147
|
+
if (!userMap) {
|
|
1148
|
+
userMap = /* @__PURE__ */ new Map();
|
|
1149
|
+
this.userAccountStore.set(userId, userMap);
|
|
1150
|
+
}
|
|
1151
|
+
userMap.set(provider.toLowerCase(), account);
|
|
1152
|
+
},
|
|
1153
|
+
getAccount: async (userId, provider) => {
|
|
1154
|
+
const userMap = this.userAccountStore.get(userId);
|
|
1155
|
+
return userMap?.get(provider.toLowerCase()) || null;
|
|
1156
|
+
},
|
|
1157
|
+
getUserAccounts: async (userId) => {
|
|
1158
|
+
const userMap = this.userAccountStore.get(userId);
|
|
1159
|
+
const result = {};
|
|
1160
|
+
if (userMap) {
|
|
1161
|
+
for (const [p, a] of userMap.entries()) {
|
|
1162
|
+
result[p] = a;
|
|
1163
|
+
}
|
|
1164
|
+
}
|
|
1165
|
+
return result;
|
|
1166
|
+
},
|
|
1167
|
+
deleteAccount: async (userId, provider) => {
|
|
1168
|
+
const userMap = this.userAccountStore.get(userId);
|
|
1169
|
+
if (userMap) {
|
|
1170
|
+
userMap.delete(provider.toLowerCase());
|
|
1171
|
+
}
|
|
1172
|
+
}
|
|
1173
|
+
}
|
|
1174
|
+
};
|
|
1175
|
+
const storage = config.storage;
|
|
1176
|
+
this.stateHandler = config.stateHandler || (storage?.stateStorage ? { storage: storage.stateStorage } : this.localStateHandler);
|
|
1177
|
+
this.sessionHandler = config.sessionHandler || (storage?.sessionStorage ? { storage: storage.sessionStorage } : this.localSessionHandler);
|
|
1178
|
+
this.resourceHandler = config.resourceHandler || (storage?.resourceStorage ? { resourceStorage: storage.resourceStorage } : this.localResourceHandler);
|
|
1179
|
+
this.accountHandler = storage?.accountStorage ? { accountStorage: storage.accountStorage } : this.localAccountHandler;
|
|
1180
|
+
const identityConfig = config.identityProvider || config.identity;
|
|
1181
|
+
if (identityConfig) {
|
|
1182
|
+
if (typeof identityConfig.signUp === "function") {
|
|
1183
|
+
this.identityProvider = identityConfig;
|
|
1184
|
+
if (this.identityProvider instanceof SelfManagedIdentityProvider) {
|
|
1185
|
+
this.credentialsManager = this.identityProvider.getCredentialsManager();
|
|
1186
|
+
}
|
|
1187
|
+
} else {
|
|
1188
|
+
const selfManaged = new SelfManagedIdentityProvider(identityConfig);
|
|
1189
|
+
this.identityProvider = selfManaged;
|
|
1190
|
+
this.credentialsManager = selfManaged.getCredentialsManager();
|
|
1191
|
+
}
|
|
1192
|
+
} else if (config.credentials !== void 0 && config.credentials.enabled !== false) {
|
|
1193
|
+
const selfManaged = new SelfManagedIdentityProvider(config.credentials);
|
|
1194
|
+
this.identityProvider = selfManaged;
|
|
1195
|
+
this.credentialsManager = selfManaged.getCredentialsManager();
|
|
913
1196
|
}
|
|
1197
|
+
const oauthProviders = this.config.providers;
|
|
914
1198
|
this.log("INFO", "Init", "Initializing Lixa instance", {
|
|
915
|
-
providers:
|
|
916
|
-
|
|
1199
|
+
providers: oauthProviders ? Object.keys(oauthProviders) : [],
|
|
1200
|
+
identityProvider: this.identityProvider ? this.identityProvider.name : void 0,
|
|
1201
|
+
identityEnabled: this.identityProvider !== void 0,
|
|
1202
|
+
credentialsEnabled: this.identityProvider !== void 0,
|
|
917
1203
|
debug: this.debug
|
|
918
1204
|
});
|
|
919
|
-
if (
|
|
920
|
-
for (const [providerName, providerConfig] of Object.entries(
|
|
1205
|
+
if (oauthProviders) {
|
|
1206
|
+
for (const [providerName, providerConfig] of Object.entries(oauthProviders)) {
|
|
921
1207
|
const name = providerName.toLowerCase();
|
|
922
1208
|
const typedConfig = providerConfig;
|
|
923
1209
|
this.validateProviderConfig(providerName, typedConfig);
|
|
@@ -946,6 +1232,20 @@ var Lixa = class _Lixa {
|
|
|
946
1232
|
* @throws InvalidProviderConfigError when required fields are missing or invalid
|
|
947
1233
|
*/
|
|
948
1234
|
validateProviderConfig(name, config) {
|
|
1235
|
+
if (!config.scopes || config.scopes.length === 0) {
|
|
1236
|
+
const p = config.provider;
|
|
1237
|
+
if (p?.defaultScopes && Array.isArray(p.defaultScopes) && p.defaultScopes.length > 0) {
|
|
1238
|
+
config.scopes = [...p.defaultScopes];
|
|
1239
|
+
} else if (p?.authScopes && Array.isArray(p.authScopes) && p.authScopes.length > 0) {
|
|
1240
|
+
config.scopes = [...p.authScopes];
|
|
1241
|
+
} else if (name === "google" || name.startsWith("google")) {
|
|
1242
|
+
config.scopes = ["openid", "profile", "email"];
|
|
1243
|
+
} else if (name === "github" || name.startsWith("github")) {
|
|
1244
|
+
config.scopes = ["read:user", "user:email"];
|
|
1245
|
+
} else if (name.startsWith("cognito")) {
|
|
1246
|
+
config.scopes = ["openid", "email", "profile"];
|
|
1247
|
+
}
|
|
1248
|
+
}
|
|
949
1249
|
const requiredFields = ["clientId", "clientSecret", "redirectUri", "scopes"];
|
|
950
1250
|
const missingFields = requiredFields.filter((field) => {
|
|
951
1251
|
const value = config[field];
|
|
@@ -1282,7 +1582,7 @@ var Lixa = class _Lixa {
|
|
|
1282
1582
|
this.log("INFO", "State", `Saved state for provider: ${providerType}`, { state: stateValue });
|
|
1283
1583
|
const authNScopes = this.resolveAuthNScopes(
|
|
1284
1584
|
providerType,
|
|
1285
|
-
providerConfig.scopes,
|
|
1585
|
+
providerConfig.scopes || [],
|
|
1286
1586
|
providerImpl,
|
|
1287
1587
|
providerConfig.allowNonAuthScopes
|
|
1288
1588
|
);
|
|
@@ -1368,7 +1668,8 @@ var Lixa = class _Lixa {
|
|
|
1368
1668
|
async handleCallback({
|
|
1369
1669
|
provider,
|
|
1370
1670
|
code,
|
|
1371
|
-
state
|
|
1671
|
+
state,
|
|
1672
|
+
sessionId
|
|
1372
1673
|
}) {
|
|
1373
1674
|
const providerType = String(provider).toLowerCase();
|
|
1374
1675
|
this.log("INFO", "Auth", `Handling OAuth callback for provider: ${providerType}`);
|
|
@@ -1437,19 +1738,40 @@ var Lixa = class _Lixa {
|
|
|
1437
1738
|
}
|
|
1438
1739
|
const sessionStorage = this.sessionHandler.sessionStorage || this.localSessionHandler.sessionStorage;
|
|
1439
1740
|
const linkingConfig = this.config.accountLinking;
|
|
1440
|
-
const mode = String(linkingConfig?.mode || "");
|
|
1441
|
-
const isLinkByEmail = mode === "AUTO_LINK_BY_VERIFIED_EMAIL" /* AUTO_LINK_BY_VERIFIED_EMAIL */ || mode === "AUTO_LINK_BY_VERIFIED_EMAIL" || mode === "linkByEmail";
|
|
1741
|
+
const mode = typeof linkingConfig === "object" ? String(linkingConfig?.mode || "") : "";
|
|
1742
|
+
const isLinkByEmail = linkingConfig === true || linkingConfig === "linkByEmail" || linkingConfig === "AUTO_LINK_BY_VERIFIED_EMAIL" /* AUTO_LINK_BY_VERIFIED_EMAIL */ || mode === "AUTO_LINK_BY_VERIFIED_EMAIL" /* AUTO_LINK_BY_VERIFIED_EMAIL */ || mode === "AUTO_LINK_BY_VERIFIED_EMAIL" || mode === "linkByEmail";
|
|
1442
1743
|
const email = extractedUserInfo?.email;
|
|
1443
1744
|
const isVerified = extractedUserInfo?.email_verified !== false;
|
|
1444
|
-
const requireVerified = linkingConfig?.requireVerifiedEmail ?? true;
|
|
1745
|
+
const requireVerified = typeof linkingConfig === "object" ? linkingConfig?.requireVerifiedEmail ?? true : true;
|
|
1445
1746
|
const canLink = isLinkByEmail && email && (!requireVerified || isVerified);
|
|
1747
|
+
if (sessionId) {
|
|
1748
|
+
const activeSession = await sessionStorage.getSession(sessionId);
|
|
1749
|
+
if (activeSession) {
|
|
1750
|
+
this.log("INFO", "AccountLinking", `Linking provider '${providerType}' directly to active session '${sessionId}'`);
|
|
1751
|
+
const linkedAcc2 = {
|
|
1752
|
+
provider: providerType,
|
|
1753
|
+
providerUserId: extractedUserInfo?.sub || extractedUserInfo?.id,
|
|
1754
|
+
email: extractedUserInfo?.email || activeSession.email,
|
|
1755
|
+
accessToken: tokens.access_token,
|
|
1756
|
+
raw: tokens,
|
|
1757
|
+
linkedAt: Date.now()
|
|
1758
|
+
};
|
|
1759
|
+
activeSession.accounts = activeSession.accounts || {};
|
|
1760
|
+
activeSession.accounts[providerType] = linkedAcc2;
|
|
1761
|
+
await sessionStorage.saveSession(sessionId, activeSession, 86400);
|
|
1762
|
+
if (this.accountHandler?.accountStorage) {
|
|
1763
|
+
const userKey = this.getUserKeyFromSession(activeSession);
|
|
1764
|
+
await this.accountHandler.accountStorage.saveAccount(userKey, providerType, linkedAcc2);
|
|
1765
|
+
}
|
|
1766
|
+
return sessionId;
|
|
1767
|
+
}
|
|
1768
|
+
}
|
|
1446
1769
|
if (canLink && sessionStorage.getSessionByEmail) {
|
|
1447
1770
|
const existingRecord = await sessionStorage.getSessionByEmail(email);
|
|
1448
1771
|
if (existingRecord) {
|
|
1449
1772
|
this.log("INFO", "AccountLinking", `Linking provider '${providerType}' to existing session for email '${email}'`);
|
|
1450
1773
|
const { sessionId: existingSessionId, session: existingSession } = existingRecord;
|
|
1451
|
-
|
|
1452
|
-
existingSession.accounts[providerType] = {
|
|
1774
|
+
const linkedAcc2 = {
|
|
1453
1775
|
provider: providerType,
|
|
1454
1776
|
providerUserId: extractedUserInfo?.sub || extractedUserInfo?.id,
|
|
1455
1777
|
email,
|
|
@@ -1457,15 +1779,18 @@ var Lixa = class _Lixa {
|
|
|
1457
1779
|
raw: tokens,
|
|
1458
1780
|
linkedAt: Date.now()
|
|
1459
1781
|
};
|
|
1782
|
+
existingSession.accounts = existingSession.accounts || {};
|
|
1783
|
+
existingSession.accounts[providerType] = linkedAcc2;
|
|
1460
1784
|
existingSession.provider = providerType;
|
|
1461
|
-
existingSession.token = tokens.access_token;
|
|
1462
|
-
existingSession.raw = tokens;
|
|
1463
1785
|
await sessionStorage.saveSession(existingSessionId, existingSession, 86400);
|
|
1786
|
+
if (this.accountHandler?.accountStorage) {
|
|
1787
|
+
const userKey = this.getUserKeyFromSession(existingSession);
|
|
1788
|
+
await this.accountHandler.accountStorage.saveAccount(userKey, providerType, linkedAcc2);
|
|
1789
|
+
}
|
|
1464
1790
|
return existingSessionId;
|
|
1465
1791
|
}
|
|
1466
1792
|
}
|
|
1467
|
-
|
|
1468
|
-
session.accounts[providerType] = {
|
|
1793
|
+
const linkedAcc = {
|
|
1469
1794
|
provider: providerType,
|
|
1470
1795
|
providerUserId: extractedUserInfo?.sub || extractedUserInfo?.id,
|
|
1471
1796
|
email: extractedUserInfo?.email,
|
|
@@ -1473,12 +1798,18 @@ var Lixa = class _Lixa {
|
|
|
1473
1798
|
raw: tokens,
|
|
1474
1799
|
linkedAt: Date.now()
|
|
1475
1800
|
};
|
|
1476
|
-
|
|
1477
|
-
session.
|
|
1478
|
-
this.
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1801
|
+
session.accounts = session.accounts || {};
|
|
1802
|
+
session.accounts[providerType] = linkedAcc;
|
|
1803
|
+
if (this.accountHandler?.accountStorage) {
|
|
1804
|
+
const userKey = this.getUserKeyFromSession(session);
|
|
1805
|
+
await this.accountHandler.accountStorage.saveAccount(userKey, providerType, linkedAcc);
|
|
1806
|
+
}
|
|
1807
|
+
const newSessionId = (0, import_crypto4.randomBytes)(32).toString("hex");
|
|
1808
|
+
session.sessionId = newSessionId;
|
|
1809
|
+
this.log("INFO", "Session", "Storing session", { sessionId: newSessionId });
|
|
1810
|
+
await sessionStorage.saveSession(newSessionId, session, 86400);
|
|
1811
|
+
this.log("INFO", "Session", "Session created successfully", { sessionId: newSessionId });
|
|
1812
|
+
return newSessionId;
|
|
1482
1813
|
}
|
|
1483
1814
|
/**
|
|
1484
1815
|
* Explicitly link a new OAuth provider account to an active session.
|
|
@@ -1564,6 +1895,10 @@ var Lixa = class _Lixa {
|
|
|
1564
1895
|
}
|
|
1565
1896
|
delete session.accounts[providerToUnlink.toLowerCase()];
|
|
1566
1897
|
await sessionStorage.saveSession(sessionId, session, 86400);
|
|
1898
|
+
if (this.accountHandler?.accountStorage) {
|
|
1899
|
+
const userKey = this.getUserKeyFromSession(session);
|
|
1900
|
+
await this.accountHandler.accountStorage.deleteAccount(userKey, providerToUnlink.toLowerCase());
|
|
1901
|
+
}
|
|
1567
1902
|
return true;
|
|
1568
1903
|
}
|
|
1569
1904
|
/**
|
|
@@ -1578,7 +1913,7 @@ var Lixa = class _Lixa {
|
|
|
1578
1913
|
* @returns The authorization URL for resource consent
|
|
1579
1914
|
*/
|
|
1580
1915
|
async getResourceAuthUrl(params) {
|
|
1581
|
-
const { sessionId, provider,
|
|
1916
|
+
const { sessionId, provider, state, prompt, extraConfig } = params;
|
|
1582
1917
|
const sessionStorage = this.sessionHandler.sessionStorage || this.localSessionHandler.sessionStorage;
|
|
1583
1918
|
const activeSession = await sessionStorage.getSession(sessionId);
|
|
1584
1919
|
if (!activeSession) {
|
|
@@ -1589,6 +1924,10 @@ var Lixa = class _Lixa {
|
|
|
1589
1924
|
if (!providerConfig) {
|
|
1590
1925
|
throw new ProviderNotConfiguredError(String(provider));
|
|
1591
1926
|
}
|
|
1927
|
+
const requestedScopes = params.scopes && params.scopes.length > 0 ? params.scopes : providerConfig.resourceScopes || [];
|
|
1928
|
+
if (requestedScopes.length === 0) {
|
|
1929
|
+
throw new Error(`No scopes specified for resource '${provider}'. Provide scopes in getResourceAuthUrl() or configure 'resourceScopes' on the provider.`);
|
|
1930
|
+
}
|
|
1592
1931
|
const providerImpl = this.getProvider(providerType, providerConfig);
|
|
1593
1932
|
const stateValue = state || (0, import_crypto4.randomBytes)(16).toString("hex");
|
|
1594
1933
|
const codeVerifier = (0, import_crypto4.randomBytes)(32).toString("hex");
|
|
@@ -1606,7 +1945,7 @@ var Lixa = class _Lixa {
|
|
|
1606
1945
|
const searchParams = new URLSearchParams({
|
|
1607
1946
|
client_id: providerConfig.clientId,
|
|
1608
1947
|
redirect_uri: providerConfig.redirectUri,
|
|
1609
|
-
scope:
|
|
1948
|
+
scope: requestedScopes.join(" "),
|
|
1610
1949
|
state: stateValue,
|
|
1611
1950
|
response_type: "code",
|
|
1612
1951
|
code_challenge: codeChallenge,
|
|
@@ -1618,7 +1957,7 @@ var Lixa = class _Lixa {
|
|
|
1618
1957
|
return `${providerImpl.authorizationEndpoint}?${searchParams.toString()}`;
|
|
1619
1958
|
}
|
|
1620
1959
|
getUserKeyFromSession(session) {
|
|
1621
|
-
return session.userId || session.email || session.
|
|
1960
|
+
return session.userId || session.email || session.sessionId || "anonymous";
|
|
1622
1961
|
}
|
|
1623
1962
|
/**
|
|
1624
1963
|
* Handles the OAuth callback for a connected resource provider and stores resource tokens bound to user account.
|
|
@@ -1648,12 +1987,13 @@ var Lixa = class _Lixa {
|
|
|
1648
1987
|
}
|
|
1649
1988
|
const tokens = await this.exchangeCodeForToken(code, providerConfig, providerImpl, codeVerifier);
|
|
1650
1989
|
const expiresAt = tokens.expires_in ? Date.now() + tokens.expires_in * 1e3 : void 0;
|
|
1990
|
+
const effectiveScopes = scopes || (tokens.scope ? tokens.scope.split(" ") : providerConfig.resourceScopes || []);
|
|
1651
1991
|
const connectedResource = {
|
|
1652
1992
|
provider: providerType,
|
|
1653
1993
|
accessToken: tokens.access_token,
|
|
1654
1994
|
refreshToken: tokens.refresh_token,
|
|
1655
1995
|
expiresAt,
|
|
1656
|
-
scopes:
|
|
1996
|
+
scopes: effectiveScopes,
|
|
1657
1997
|
raw: tokens,
|
|
1658
1998
|
connectedAt: Date.now()
|
|
1659
1999
|
};
|
|
@@ -1665,6 +2005,40 @@ var Lixa = class _Lixa {
|
|
|
1665
2005
|
await sessionStorage.saveSession(sessionId, activeSession, 86400);
|
|
1666
2006
|
return activeSession;
|
|
1667
2007
|
}
|
|
2008
|
+
/**
|
|
2009
|
+
* Retrieves configured default resource scopes for a provider.
|
|
2010
|
+
*
|
|
2011
|
+
* @param provider - Provider name (e.g. 'github', 'google')
|
|
2012
|
+
* @returns Array of configured resource scopes, or undefined if not configured
|
|
2013
|
+
*/
|
|
2014
|
+
getResourceScopes(provider) {
|
|
2015
|
+
const providerConfig = this.findProviderByType(String(provider).toLowerCase());
|
|
2016
|
+
return providerConfig?.resourceScopes;
|
|
2017
|
+
}
|
|
2018
|
+
/**
|
|
2019
|
+
* Returns the resolved session cookie name.
|
|
2020
|
+
* Dynamically reflects any changes to the active identity provider.
|
|
2021
|
+
*
|
|
2022
|
+
* @param req - Optional request object for multi-tenant request-scoped cookie resolution
|
|
2023
|
+
* @returns Resolved session cookie name
|
|
2024
|
+
*/
|
|
2025
|
+
getSessionCookieName(req) {
|
|
2026
|
+
if (typeof this.sessionCookieResolver === "function") {
|
|
2027
|
+
return this.sessionCookieResolver(this, req);
|
|
2028
|
+
}
|
|
2029
|
+
if (typeof this.sessionCookieResolver === "string" && this.sessionCookieResolver.length > 0) {
|
|
2030
|
+
return this.sessionCookieResolver;
|
|
2031
|
+
}
|
|
2032
|
+
return DEFAULT_SESSION_COOKIE_NAME;
|
|
2033
|
+
}
|
|
2034
|
+
/**
|
|
2035
|
+
* Sets or updates the session cookie name or dynamic resolver on this instance.
|
|
2036
|
+
*
|
|
2037
|
+
* @param resolver - Static cookie name or dynamic resolver function
|
|
2038
|
+
*/
|
|
2039
|
+
setSessionCookieName(resolver) {
|
|
2040
|
+
this.sessionCookieResolver = resolver;
|
|
2041
|
+
}
|
|
1668
2042
|
/**
|
|
1669
2043
|
* Retrieves a connected resource for a specific User ID / Email directly (independent of session IDs).
|
|
1670
2044
|
* Automatically refreshes expired access tokens if a refresh token is present.
|
|
@@ -1845,7 +2219,16 @@ var Lixa = class _Lixa {
|
|
|
1845
2219
|
*/
|
|
1846
2220
|
async fetchSessionInfo(sessionId) {
|
|
1847
2221
|
const sessionStorage = this.sessionHandler.sessionStorage || this.localSessionHandler.sessionStorage;
|
|
1848
|
-
|
|
2222
|
+
const session = await sessionStorage.getSession(sessionId);
|
|
2223
|
+
if (!session) return null;
|
|
2224
|
+
if (this.accountHandler?.accountStorage) {
|
|
2225
|
+
const userKey = this.getUserKeyFromSession(session);
|
|
2226
|
+
const persistentAccounts = await this.accountHandler.accountStorage.getUserAccounts(userKey);
|
|
2227
|
+
if (persistentAccounts && Object.keys(persistentAccounts).length > 0) {
|
|
2228
|
+
session.accounts = { ...persistentAccounts, ...session.accounts || {} };
|
|
2229
|
+
}
|
|
2230
|
+
}
|
|
2231
|
+
return session;
|
|
1849
2232
|
}
|
|
1850
2233
|
/**
|
|
1851
2234
|
* Deletes a session from session storage (e.g. on logout).
|
|
@@ -1896,36 +2279,64 @@ var Lixa = class _Lixa {
|
|
|
1896
2279
|
return response.json();
|
|
1897
2280
|
}
|
|
1898
2281
|
/**
|
|
1899
|
-
* Checks if
|
|
2282
|
+
* Checks if an identity provider (Self-Managed Database, AWS Cognito, Auth0, Okta, etc.) is configured.
|
|
2283
|
+
*
|
|
2284
|
+
* @returns True if identity provider is configured and available
|
|
2285
|
+
*/
|
|
2286
|
+
isIdentityEnabled() {
|
|
2287
|
+
return this.identityProvider !== void 0;
|
|
2288
|
+
}
|
|
2289
|
+
/**
|
|
2290
|
+
* Checks if credentials / identity authentication is configured and enabled.
|
|
1900
2291
|
*
|
|
1901
|
-
* @returns True if credentials authentication is available
|
|
2292
|
+
* @returns True if credentials / identity authentication is available
|
|
1902
2293
|
*/
|
|
1903
2294
|
isCredentialsEnabled() {
|
|
1904
|
-
return this.
|
|
2295
|
+
return this.identityProvider !== void 0;
|
|
2296
|
+
}
|
|
2297
|
+
/**
|
|
2298
|
+
* Returns the configured IdentityProvider instance.
|
|
2299
|
+
*/
|
|
2300
|
+
getIdentityProvider() {
|
|
2301
|
+
return this.identityProvider;
|
|
2302
|
+
}
|
|
2303
|
+
/**
|
|
2304
|
+
* Dynamically sets or updates the active identity provider (e.g. SelfManaged, Cognito, Auth0, Okta).
|
|
2305
|
+
*
|
|
2306
|
+
* @param provider - Identity provider instance or undefined to disable
|
|
2307
|
+
*/
|
|
2308
|
+
setIdentityProvider(provider) {
|
|
2309
|
+
this.identityProvider = provider;
|
|
2310
|
+
if (provider instanceof SelfManagedIdentityProvider) {
|
|
2311
|
+
this.credentialsManager = provider.getCredentialsManager();
|
|
2312
|
+
} else {
|
|
2313
|
+
this.credentialsManager = void 0;
|
|
2314
|
+
}
|
|
1905
2315
|
}
|
|
1906
2316
|
/**
|
|
1907
|
-
* Returns the underlying CredentialsManager instance if
|
|
2317
|
+
* Returns the underlying CredentialsManager instance if using Self-Managed identity.
|
|
1908
2318
|
*/
|
|
1909
2319
|
getCredentialsManager() {
|
|
1910
2320
|
return this.credentialsManager;
|
|
1911
2321
|
}
|
|
1912
2322
|
/**
|
|
1913
|
-
* Registers a new user with
|
|
1914
|
-
* Automatically
|
|
1915
|
-
* stores credentials, and creates a session (unless autoCreateSessionOnSignUp is false).
|
|
2323
|
+
* Registers a new user with the configured identity provider (Self-Managed DB, Cognito, Auth0, Okta).
|
|
2324
|
+
* Automatically creates an active session unless autoCreateSessionOnSignUp is explicitly set to false.
|
|
1916
2325
|
*
|
|
1917
2326
|
* @param params - Registration parameters (identifier, password, email, username, metadata)
|
|
1918
|
-
* @returns Created user
|
|
2327
|
+
* @returns Created user identity and optional active session
|
|
1919
2328
|
* @throws WeakPasswordError if password does not meet policy requirements
|
|
1920
2329
|
* @throws UserAlreadyExistsError if identifier is already registered
|
|
1921
|
-
* @throws
|
|
2330
|
+
* @throws IdentityNotConfiguredError if identity authentication is not configured
|
|
1922
2331
|
*/
|
|
1923
2332
|
async signUp(params) {
|
|
1924
|
-
if (!this.
|
|
1925
|
-
throw new
|
|
2333
|
+
if (!this.identityProvider) {
|
|
2334
|
+
throw new IdentityNotConfiguredError();
|
|
1926
2335
|
}
|
|
1927
|
-
|
|
1928
|
-
const
|
|
2336
|
+
const rawProviderName = this.identityProvider.name;
|
|
2337
|
+
const providerName = rawProviderName === "self-managed" ? "credentials" : rawProviderName;
|
|
2338
|
+
this.log("INFO", "Identity", `Processing signUp request via ${providerName}`, { identifier: params.identifier });
|
|
2339
|
+
const user = await this.identityProvider.signUp(params);
|
|
1929
2340
|
const autoSession = this.config.credentials?.autoCreateSessionOnSignUp ?? true;
|
|
1930
2341
|
if (!autoSession) {
|
|
1931
2342
|
return { user };
|
|
@@ -1933,8 +2344,9 @@ var Lixa = class _Lixa {
|
|
|
1933
2344
|
const sessionId = (0, import_crypto4.randomBytes)(16).toString("hex");
|
|
1934
2345
|
const token = (0, import_crypto4.randomBytes)(32).toString("hex");
|
|
1935
2346
|
const ttl = this.config.credentials?.sessionTtlSeconds ?? 86400;
|
|
2347
|
+
const accountKey = providerName;
|
|
1936
2348
|
const credentialsAccount = {
|
|
1937
|
-
provider:
|
|
2349
|
+
provider: providerName,
|
|
1938
2350
|
providerUserId: user.id,
|
|
1939
2351
|
email: user.email,
|
|
1940
2352
|
accessToken: token,
|
|
@@ -1946,67 +2358,71 @@ var Lixa = class _Lixa {
|
|
|
1946
2358
|
linkedAt: Date.now()
|
|
1947
2359
|
};
|
|
1948
2360
|
const session = {
|
|
1949
|
-
|
|
2361
|
+
sessionId,
|
|
1950
2362
|
userId: user.id,
|
|
1951
2363
|
email: user.email,
|
|
1952
|
-
|
|
1953
|
-
provider: "credentials",
|
|
2364
|
+
provider: providerName,
|
|
1954
2365
|
accounts: {
|
|
1955
|
-
|
|
2366
|
+
[accountKey]: credentialsAccount
|
|
1956
2367
|
}
|
|
1957
2368
|
};
|
|
1958
2369
|
const sessionStorage = this.sessionHandler.sessionStorage || this.localSessionHandler.sessionStorage;
|
|
1959
2370
|
await sessionStorage.saveSession(sessionId, session, ttl);
|
|
1960
|
-
this.log("INFO", "
|
|
2371
|
+
this.log("INFO", "Identity", "Created session on signUp", { userId: user.id, sessionId, provider: providerName });
|
|
1961
2372
|
return { user, sessionId, session };
|
|
1962
2373
|
}
|
|
1963
2374
|
/**
|
|
1964
|
-
* Authenticates a user with
|
|
1965
|
-
*
|
|
1966
|
-
* If account linking is configured with AUTO_LINK_BY_VERIFIED_EMAIL, merges with existing session.
|
|
2375
|
+
* Authenticates a user with credentials via the configured identity provider (Self-Managed DB, Cognito, Auth0, Okta).
|
|
2376
|
+
* Creates an active session and automatically links with existing sessions when AUTO_LINK_BY_VERIFIED_EMAIL is configured.
|
|
1967
2377
|
*
|
|
1968
2378
|
* @param params - Sign-in parameters (identifier, password)
|
|
1969
2379
|
* @returns Authenticated user, session ID, and session object
|
|
1970
2380
|
* @throws InvalidCredentialsError if authentication fails
|
|
1971
|
-
* @throws
|
|
2381
|
+
* @throws IdentityNotConfiguredError if identity authentication is not configured
|
|
1972
2382
|
*/
|
|
1973
2383
|
async signIn(params) {
|
|
1974
|
-
if (!this.
|
|
1975
|
-
throw new
|
|
2384
|
+
if (!this.identityProvider) {
|
|
2385
|
+
throw new IdentityNotConfiguredError();
|
|
1976
2386
|
}
|
|
1977
2387
|
const lookupKey = params.username || params.identifier;
|
|
1978
|
-
|
|
1979
|
-
const
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
2388
|
+
const rawProviderName = this.identityProvider.name;
|
|
2389
|
+
const providerName = rawProviderName === "self-managed" ? "credentials" : rawProviderName;
|
|
2390
|
+
this.log("INFO", "Identity", `Processing signIn request via ${providerName}`, { identifier: lookupKey });
|
|
2391
|
+
const authResult = await this.identityProvider.signIn(params);
|
|
2392
|
+
const user = authResult.user;
|
|
2393
|
+
const tokens = authResult.tokens;
|
|
1984
2394
|
const ttl = this.config.credentials?.sessionTtlSeconds ?? 86400;
|
|
1985
|
-
const token = (0, import_crypto4.randomBytes)(32).toString("hex");
|
|
2395
|
+
const token = tokens?.accessToken || (0, import_crypto4.randomBytes)(32).toString("hex");
|
|
2396
|
+
const rawTokens = {
|
|
2397
|
+
access_token: token,
|
|
2398
|
+
token_type: tokens?.tokenType || "Bearer",
|
|
2399
|
+
expires_in: tokens?.expiresIn || ttl,
|
|
2400
|
+
id_token: tokens?.idToken,
|
|
2401
|
+
refresh_token: tokens?.refreshToken,
|
|
2402
|
+
...tokens?.raw
|
|
2403
|
+
};
|
|
2404
|
+
const accountKey = providerName === "self-managed" ? "credentials" : providerName;
|
|
1986
2405
|
const credentialsAccount = {
|
|
1987
|
-
provider:
|
|
2406
|
+
provider: providerName,
|
|
1988
2407
|
providerUserId: user.id,
|
|
1989
2408
|
email: user.email,
|
|
1990
2409
|
accessToken: token,
|
|
1991
|
-
raw:
|
|
1992
|
-
access_token: token,
|
|
1993
|
-
token_type: "Bearer",
|
|
1994
|
-
expires_in: ttl
|
|
1995
|
-
},
|
|
2410
|
+
raw: rawTokens,
|
|
1996
2411
|
linkedAt: Date.now()
|
|
1997
2412
|
};
|
|
1998
2413
|
const sessionStorage = this.sessionHandler.sessionStorage || this.localSessionHandler.sessionStorage;
|
|
1999
|
-
const
|
|
2000
|
-
const
|
|
2414
|
+
const linkingConfig = this.config.accountLinking;
|
|
2415
|
+
const linkingMode = typeof linkingConfig === "object" ? linkingConfig?.mode : void 0;
|
|
2416
|
+
const isAutoLink = linkingConfig === true || linkingConfig === "linkByEmail" || linkingConfig === "AUTO_LINK_BY_VERIFIED_EMAIL" /* AUTO_LINK_BY_VERIFIED_EMAIL */ || linkingMode === "AUTO_LINK_BY_VERIFIED_EMAIL" /* AUTO_LINK_BY_VERIFIED_EMAIL */ || linkingMode === "AUTO_LINK_BY_VERIFIED_EMAIL" || linkingMode === "linkByEmail";
|
|
2001
2417
|
if (isAutoLink && user.email && sessionStorage.getSessionByEmail) {
|
|
2002
2418
|
const existing = await sessionStorage.getSessionByEmail(user.email);
|
|
2003
2419
|
if (existing) {
|
|
2004
2420
|
const mergedSession = { ...existing.session };
|
|
2005
|
-
mergedSession.accounts = { ...mergedSession.accounts || {},
|
|
2421
|
+
mergedSession.accounts = { ...mergedSession.accounts || {}, [accountKey]: credentialsAccount };
|
|
2006
2422
|
if (!mergedSession.userId) mergedSession.userId = user.id;
|
|
2007
2423
|
if (!mergedSession.email) mergedSession.email = user.email;
|
|
2008
2424
|
await sessionStorage.saveSession(existing.sessionId, mergedSession, ttl);
|
|
2009
|
-
this.log("INFO", "AccountLinking",
|
|
2425
|
+
this.log("INFO", "AccountLinking", `Linked ${providerName} to existing session by email`, {
|
|
2010
2426
|
sessionId: existing.sessionId,
|
|
2011
2427
|
email: user.email
|
|
2012
2428
|
});
|
|
@@ -2019,31 +2435,46 @@ var Lixa = class _Lixa {
|
|
|
2019
2435
|
}
|
|
2020
2436
|
const sessionId = (0, import_crypto4.randomBytes)(16).toString("hex");
|
|
2021
2437
|
const session = {
|
|
2022
|
-
|
|
2438
|
+
sessionId,
|
|
2023
2439
|
userId: user.id,
|
|
2024
2440
|
email: user.email,
|
|
2025
|
-
|
|
2026
|
-
provider: "credentials",
|
|
2441
|
+
provider: providerName,
|
|
2027
2442
|
accounts: {
|
|
2028
|
-
|
|
2443
|
+
[accountKey]: credentialsAccount
|
|
2029
2444
|
}
|
|
2030
2445
|
};
|
|
2446
|
+
const userKey = this.getUserKeyFromSession(session);
|
|
2447
|
+
if (this.accountHandler?.accountStorage) {
|
|
2448
|
+
const persistentAccounts = await this.accountHandler.accountStorage.getUserAccounts(userKey);
|
|
2449
|
+
if (persistentAccounts && Object.keys(persistentAccounts).length > 0) {
|
|
2450
|
+
session.accounts = { ...persistentAccounts, ...session.accounts };
|
|
2451
|
+
}
|
|
2452
|
+
await this.accountHandler.accountStorage.saveAccount(userKey, accountKey, credentialsAccount);
|
|
2453
|
+
}
|
|
2031
2454
|
await sessionStorage.saveSession(sessionId, session, ttl);
|
|
2032
|
-
this.log("INFO", "
|
|
2455
|
+
this.log("INFO", "Identity", `User signed in successfully via ${providerName}`, { userId: user.id, sessionId });
|
|
2033
2456
|
return { user, sessionId, session };
|
|
2034
2457
|
}
|
|
2035
2458
|
/**
|
|
2036
2459
|
* Verifies username/email and password credentials without generating a session.
|
|
2037
2460
|
*
|
|
2038
2461
|
* @param params - Verification parameters (identifier, password)
|
|
2039
|
-
* @returns User credentials
|
|
2040
|
-
* @throws
|
|
2462
|
+
* @returns User credentials/identity or null if invalid
|
|
2463
|
+
* @throws IdentityNotConfiguredError if identity auth is not configured
|
|
2041
2464
|
*/
|
|
2042
2465
|
async verifyCredentials(params) {
|
|
2043
|
-
if (!this.
|
|
2044
|
-
throw new
|
|
2466
|
+
if (!this.identityProvider) {
|
|
2467
|
+
throw new IdentityNotConfiguredError();
|
|
2468
|
+
}
|
|
2469
|
+
if (typeof this.identityProvider.verifyCredentials === "function") {
|
|
2470
|
+
return this.identityProvider.verifyCredentials(params);
|
|
2471
|
+
}
|
|
2472
|
+
try {
|
|
2473
|
+
const result = await this.identityProvider.signIn(params);
|
|
2474
|
+
return result.user;
|
|
2475
|
+
} catch {
|
|
2476
|
+
return null;
|
|
2045
2477
|
}
|
|
2046
|
-
return this.credentialsManager.verifyCredentials(params);
|
|
2047
2478
|
}
|
|
2048
2479
|
/**
|
|
2049
2480
|
* Updates a user's password after verifying the current password and enforcing policy on the new password.
|
|
@@ -2053,17 +2484,140 @@ var Lixa = class _Lixa {
|
|
|
2053
2484
|
* @throws UserNotFoundError if user is not found
|
|
2054
2485
|
* @throws InvalidCredentialsError if current password is incorrect
|
|
2055
2486
|
* @throws WeakPasswordError if new password does not meet policy requirements
|
|
2056
|
-
* @throws
|
|
2487
|
+
* @throws IdentityNotConfiguredError if identity auth is not configured
|
|
2057
2488
|
*/
|
|
2058
2489
|
async changePassword(params) {
|
|
2059
|
-
if (!this.
|
|
2060
|
-
throw new
|
|
2490
|
+
if (!this.identityProvider) {
|
|
2491
|
+
throw new IdentityNotConfiguredError();
|
|
2061
2492
|
}
|
|
2062
|
-
this.
|
|
2493
|
+
if (typeof this.identityProvider.changePassword !== "function") {
|
|
2494
|
+
throw new IdentityProviderError(
|
|
2495
|
+
`Password change is not supported by the '${this.identityProvider.name}' identity provider`,
|
|
2496
|
+
this.identityProvider.name
|
|
2497
|
+
);
|
|
2498
|
+
}
|
|
2499
|
+
this.log("INFO", "Identity", "Processing changePassword request", {
|
|
2063
2500
|
userId: params.userId,
|
|
2064
2501
|
identifier: params.identifier
|
|
2065
2502
|
});
|
|
2066
|
-
return this.
|
|
2503
|
+
return this.identityProvider.changePassword(params);
|
|
2504
|
+
}
|
|
2505
|
+
/**
|
|
2506
|
+
* Initiates a password reset (forgot password flow) through the configured identity provider.
|
|
2507
|
+
*
|
|
2508
|
+
* @param params - Forgot password parameters (identifier, optional metadata)
|
|
2509
|
+
* @returns ForgotPasswordResult indicating status and delivery medium (email/SMS)
|
|
2510
|
+
* @throws IdentityNotConfiguredError if identity auth is not configured
|
|
2511
|
+
*/
|
|
2512
|
+
async forgotPassword(params) {
|
|
2513
|
+
if (!this.identityProvider) {
|
|
2514
|
+
throw new IdentityNotConfiguredError();
|
|
2515
|
+
}
|
|
2516
|
+
if (typeof this.identityProvider.forgotPassword !== "function") {
|
|
2517
|
+
throw new IdentityProviderError(
|
|
2518
|
+
`Password reset request is not supported by the '${this.identityProvider.name}' identity provider`,
|
|
2519
|
+
this.identityProvider.name
|
|
2520
|
+
);
|
|
2521
|
+
}
|
|
2522
|
+
this.log("INFO", "Identity", "Processing forgotPassword request", { identifier: params.identifier });
|
|
2523
|
+
return this.identityProvider.forgotPassword(params);
|
|
2524
|
+
}
|
|
2525
|
+
/**
|
|
2526
|
+
* Confirms a password reset using a verification code / token and sets the new password.
|
|
2527
|
+
*
|
|
2528
|
+
* @param params - Verification code, identifier, and new password
|
|
2529
|
+
* @returns True if password reset was successfully confirmed
|
|
2530
|
+
* @throws IdentityNotConfiguredError if identity auth is not configured
|
|
2531
|
+
*/
|
|
2532
|
+
async confirmPasswordReset(params) {
|
|
2533
|
+
if (!this.identityProvider) {
|
|
2534
|
+
throw new IdentityNotConfiguredError();
|
|
2535
|
+
}
|
|
2536
|
+
if (typeof this.identityProvider.confirmPasswordReset !== "function") {
|
|
2537
|
+
throw new IdentityProviderError(
|
|
2538
|
+
`Confirm password reset is not supported by the '${this.identityProvider.name}' identity provider`,
|
|
2539
|
+
this.identityProvider.name
|
|
2540
|
+
);
|
|
2541
|
+
}
|
|
2542
|
+
this.log("INFO", "Identity", "Processing confirmPasswordReset request", { identifier: params.identifier });
|
|
2543
|
+
return this.identityProvider.confirmPasswordReset(params);
|
|
2544
|
+
}
|
|
2545
|
+
/**
|
|
2546
|
+
* Confirms user account registration using a verification code.
|
|
2547
|
+
*
|
|
2548
|
+
* @param params - Verification parameters including identifier and confirmationCode
|
|
2549
|
+
* @returns True if confirmation was successful
|
|
2550
|
+
* @throws IdentityNotConfiguredError if identity auth is not configured
|
|
2551
|
+
* @throws IdentityProviderError if identity provider does not support confirmation
|
|
2552
|
+
*/
|
|
2553
|
+
async confirmSignUp(params) {
|
|
2554
|
+
if (!this.identityProvider) {
|
|
2555
|
+
throw new IdentityNotConfiguredError();
|
|
2556
|
+
}
|
|
2557
|
+
if (typeof this.identityProvider.confirmSignUp !== "function") {
|
|
2558
|
+
throw new IdentityProviderError(
|
|
2559
|
+
`Account confirmation is not supported by the '${this.identityProvider.name}' identity provider`,
|
|
2560
|
+
this.identityProvider.name
|
|
2561
|
+
);
|
|
2562
|
+
}
|
|
2563
|
+
this.log("INFO", "Identity", "Processing confirmSignUp request", { identifier: params.identifier });
|
|
2564
|
+
return this.identityProvider.confirmSignUp(params);
|
|
2565
|
+
}
|
|
2566
|
+
/**
|
|
2567
|
+
* Resends the sign up confirmation code to the user.
|
|
2568
|
+
*
|
|
2569
|
+
* @param params - Resend parameters including user identifier
|
|
2570
|
+
* @returns Details about the code delivery (medium, destination)
|
|
2571
|
+
* @throws IdentityNotConfiguredError if identity auth is not configured
|
|
2572
|
+
* @throws IdentityProviderError if identity provider does not support resending codes
|
|
2573
|
+
*/
|
|
2574
|
+
async resendConfirmationCode(params) {
|
|
2575
|
+
if (!this.identityProvider) {
|
|
2576
|
+
throw new IdentityNotConfiguredError();
|
|
2577
|
+
}
|
|
2578
|
+
if (typeof this.identityProvider.resendConfirmationCode !== "function") {
|
|
2579
|
+
throw new IdentityProviderError(
|
|
2580
|
+
`Resending confirmation code is not supported by the '${this.identityProvider.name}' identity provider`,
|
|
2581
|
+
this.identityProvider.name
|
|
2582
|
+
);
|
|
2583
|
+
}
|
|
2584
|
+
this.log("INFO", "Identity", "Processing resendConfirmationCode request", { identifier: params.identifier });
|
|
2585
|
+
return this.identityProvider.resendConfirmationCode(params);
|
|
2586
|
+
}
|
|
2587
|
+
/**
|
|
2588
|
+
* Retrieves a user by their unique ID from the configured identity provider.
|
|
2589
|
+
*
|
|
2590
|
+
* @param id - Unique user ID
|
|
2591
|
+
* @returns UserIdentity or null if not found
|
|
2592
|
+
*/
|
|
2593
|
+
async getUserById(id) {
|
|
2594
|
+
if (!this.identityProvider || typeof this.identityProvider.getUserById !== "function") {
|
|
2595
|
+
return null;
|
|
2596
|
+
}
|
|
2597
|
+
return this.identityProvider.getUserById(id);
|
|
2598
|
+
}
|
|
2599
|
+
/**
|
|
2600
|
+
* Retrieves a user by their identifier (username or email) from the configured identity provider.
|
|
2601
|
+
*
|
|
2602
|
+
* @param identifier - Username or email string
|
|
2603
|
+
* @returns UserIdentity or null if not found
|
|
2604
|
+
*/
|
|
2605
|
+
async getUserByIdentifier(identifier) {
|
|
2606
|
+
if (!this.identityProvider || typeof this.identityProvider.getUserByIdentifier !== "function") {
|
|
2607
|
+
return null;
|
|
2608
|
+
}
|
|
2609
|
+
return this.identityProvider.getUserByIdentifier(identifier);
|
|
2610
|
+
}
|
|
2611
|
+
/**
|
|
2612
|
+
* Deletes a user account from the configured identity provider.
|
|
2613
|
+
*
|
|
2614
|
+
* @param id - Unique user ID
|
|
2615
|
+
*/
|
|
2616
|
+
async deleteUser(id) {
|
|
2617
|
+
if (!this.identityProvider || typeof this.identityProvider.deleteUser !== "function") {
|
|
2618
|
+
return;
|
|
2619
|
+
}
|
|
2620
|
+
await this.identityProvider.deleteUser(id);
|
|
2067
2621
|
}
|
|
2068
2622
|
findProviderByType(providerType) {
|
|
2069
2623
|
for (const [key, value] of Object.entries(this.config.providers || {})) {
|
|
@@ -2075,125 +2629,6 @@ var Lixa = class _Lixa {
|
|
|
2075
2629
|
}
|
|
2076
2630
|
};
|
|
2077
2631
|
|
|
2078
|
-
// src/utils/cookies.ts
|
|
2079
|
-
var DEFAULT_SESSION_COOKIE_NAME = "lixa_session";
|
|
2080
|
-
var DEFAULT_STATE_COOKIE_NAME = "lixa_oauth_state";
|
|
2081
|
-
var DEFAULT_SESSION_MAX_AGE_SECONDS = 24 * 60 * 60;
|
|
2082
|
-
var DEFAULT_STATE_MAX_AGE_SECONDS = 5 * 60;
|
|
2083
|
-
function isProductionEnvironment() {
|
|
2084
|
-
return typeof process !== "undefined" && process.env?.NODE_ENV === "production";
|
|
2085
|
-
}
|
|
2086
|
-
function serializeCookie(name, value, options) {
|
|
2087
|
-
const isProd = isProductionEnvironment();
|
|
2088
|
-
const path = options?.path ?? "/";
|
|
2089
|
-
const httpOnly = options?.httpOnly ?? true;
|
|
2090
|
-
const secure = options?.secure ?? isProd;
|
|
2091
|
-
const sameSite = options?.sameSite ?? "lax";
|
|
2092
|
-
const parts = [`${encodeURIComponent(name)}=${encodeURIComponent(value)}`];
|
|
2093
|
-
if (path) {
|
|
2094
|
-
parts.push(`Path=${path}`);
|
|
2095
|
-
}
|
|
2096
|
-
if (typeof options?.maxAge === "number") {
|
|
2097
|
-
parts.push(`Max-Age=${Math.floor(options.maxAge)}`);
|
|
2098
|
-
const expires = new Date(Date.now() + options.maxAge * 1e3).toUTCString();
|
|
2099
|
-
parts.push(`Expires=${expires}`);
|
|
2100
|
-
}
|
|
2101
|
-
if (options?.domain) {
|
|
2102
|
-
parts.push(`Domain=${options.domain}`);
|
|
2103
|
-
}
|
|
2104
|
-
if (httpOnly) {
|
|
2105
|
-
parts.push("HttpOnly");
|
|
2106
|
-
}
|
|
2107
|
-
if (secure) {
|
|
2108
|
-
parts.push("Secure");
|
|
2109
|
-
}
|
|
2110
|
-
if (sameSite) {
|
|
2111
|
-
const capitalized = sameSite.charAt(0).toUpperCase() + sameSite.slice(1).toLowerCase();
|
|
2112
|
-
parts.push(`SameSite=${capitalized}`);
|
|
2113
|
-
}
|
|
2114
|
-
return parts.join("; ");
|
|
2115
|
-
}
|
|
2116
|
-
function createSessionCookie(sessionId, options) {
|
|
2117
|
-
const isProd = isProductionEnvironment();
|
|
2118
|
-
const resolvedOptions = {
|
|
2119
|
-
name: options?.name || DEFAULT_SESSION_COOKIE_NAME,
|
|
2120
|
-
path: options?.path ?? "/",
|
|
2121
|
-
maxAge: options?.maxAge ?? DEFAULT_SESSION_MAX_AGE_SECONDS,
|
|
2122
|
-
httpOnly: options?.httpOnly ?? true,
|
|
2123
|
-
secure: options?.secure ?? isProd,
|
|
2124
|
-
sameSite: options?.sameSite ?? "lax",
|
|
2125
|
-
domain: options?.domain
|
|
2126
|
-
};
|
|
2127
|
-
const name = resolvedOptions.name;
|
|
2128
|
-
const header = serializeCookie(name, sessionId, resolvedOptions);
|
|
2129
|
-
return {
|
|
2130
|
-
name,
|
|
2131
|
-
value: sessionId,
|
|
2132
|
-
options: resolvedOptions,
|
|
2133
|
-
header
|
|
2134
|
-
};
|
|
2135
|
-
}
|
|
2136
|
-
function clearSessionCookie(options) {
|
|
2137
|
-
const isProd = isProductionEnvironment();
|
|
2138
|
-
const resolvedOptions = {
|
|
2139
|
-
name: options?.name || DEFAULT_SESSION_COOKIE_NAME,
|
|
2140
|
-
path: options?.path ?? "/",
|
|
2141
|
-
maxAge: 0,
|
|
2142
|
-
httpOnly: options?.httpOnly ?? true,
|
|
2143
|
-
secure: options?.secure ?? isProd,
|
|
2144
|
-
sameSite: options?.sameSite ?? "lax",
|
|
2145
|
-
domain: options?.domain
|
|
2146
|
-
};
|
|
2147
|
-
const name = resolvedOptions.name;
|
|
2148
|
-
const header = serializeCookie(name, "", resolvedOptions);
|
|
2149
|
-
return {
|
|
2150
|
-
name,
|
|
2151
|
-
value: "",
|
|
2152
|
-
options: resolvedOptions,
|
|
2153
|
-
header
|
|
2154
|
-
};
|
|
2155
|
-
}
|
|
2156
|
-
function createStateCookie(state, options) {
|
|
2157
|
-
const isProd = isProductionEnvironment();
|
|
2158
|
-
const resolvedOptions = {
|
|
2159
|
-
name: options?.name || DEFAULT_STATE_COOKIE_NAME,
|
|
2160
|
-
path: options?.path ?? "/",
|
|
2161
|
-
maxAge: options?.maxAge ?? DEFAULT_STATE_MAX_AGE_SECONDS,
|
|
2162
|
-
httpOnly: options?.httpOnly ?? true,
|
|
2163
|
-
secure: options?.secure ?? isProd,
|
|
2164
|
-
sameSite: options?.sameSite ?? "lax",
|
|
2165
|
-
domain: options?.domain
|
|
2166
|
-
};
|
|
2167
|
-
const name = resolvedOptions.name;
|
|
2168
|
-
const header = serializeCookie(name, state, resolvedOptions);
|
|
2169
|
-
return {
|
|
2170
|
-
name,
|
|
2171
|
-
value: state,
|
|
2172
|
-
options: resolvedOptions,
|
|
2173
|
-
header
|
|
2174
|
-
};
|
|
2175
|
-
}
|
|
2176
|
-
function clearStateCookie(options) {
|
|
2177
|
-
const isProd = isProductionEnvironment();
|
|
2178
|
-
const resolvedOptions = {
|
|
2179
|
-
name: options?.name || DEFAULT_STATE_COOKIE_NAME,
|
|
2180
|
-
path: options?.path ?? "/",
|
|
2181
|
-
maxAge: 0,
|
|
2182
|
-
httpOnly: options?.httpOnly ?? true,
|
|
2183
|
-
secure: options?.secure ?? isProd,
|
|
2184
|
-
sameSite: options?.sameSite ?? "lax",
|
|
2185
|
-
domain: options?.domain
|
|
2186
|
-
};
|
|
2187
|
-
const name = resolvedOptions.name;
|
|
2188
|
-
const header = serializeCookie(name, "", resolvedOptions);
|
|
2189
|
-
return {
|
|
2190
|
-
name,
|
|
2191
|
-
value: "",
|
|
2192
|
-
options: resolvedOptions,
|
|
2193
|
-
header
|
|
2194
|
-
};
|
|
2195
|
-
}
|
|
2196
|
-
|
|
2197
2632
|
// src/credentials/index.ts
|
|
2198
2633
|
var credentials_exports = {};
|
|
2199
2634
|
__export(credentials_exports, {
|
|
@@ -2203,6 +2638,12 @@ __export(credentials_exports, {
|
|
|
2203
2638
|
ScryptPasswordHasher: () => ScryptPasswordHasher,
|
|
2204
2639
|
validatePasswordPolicy: () => validatePasswordPolicy
|
|
2205
2640
|
});
|
|
2641
|
+
|
|
2642
|
+
// src/identity/index.ts
|
|
2643
|
+
var identity_exports = {};
|
|
2644
|
+
__export(identity_exports, {
|
|
2645
|
+
SelfManagedIdentityProvider: () => SelfManagedIdentityProvider
|
|
2646
|
+
});
|
|
2206
2647
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2207
2648
|
0 && (module.exports = {
|
|
2208
2649
|
AccountLinkingStrategy,
|
|
@@ -2214,6 +2655,8 @@ __export(credentials_exports, {
|
|
|
2214
2655
|
DEFAULT_STATE_COOKIE_NAME,
|
|
2215
2656
|
DEFAULT_STATE_MAX_AGE_SECONDS,
|
|
2216
2657
|
EmailNotVerifiedError,
|
|
2658
|
+
IdentityNotConfiguredError,
|
|
2659
|
+
IdentityProviderError,
|
|
2217
2660
|
InvalidCredentialsError,
|
|
2218
2661
|
InvalidOAuthCallbackError,
|
|
2219
2662
|
InvalidProviderConfigError,
|
|
@@ -2225,6 +2668,7 @@ __export(credentials_exports, {
|
|
|
2225
2668
|
ProviderNotConfiguredError,
|
|
2226
2669
|
RefreshTokenError,
|
|
2227
2670
|
ScryptPasswordHasher,
|
|
2671
|
+
SelfManagedIdentityProvider,
|
|
2228
2672
|
SessionNotFoundError,
|
|
2229
2673
|
TokenExchangeError,
|
|
2230
2674
|
UserAlreadyExistsError,
|
|
@@ -2239,6 +2683,7 @@ __export(credentials_exports, {
|
|
|
2239
2683
|
determineProviderFromIssuer,
|
|
2240
2684
|
extractUserInfo,
|
|
2241
2685
|
fetchUserInfo,
|
|
2686
|
+
identity,
|
|
2242
2687
|
isProductionEnvironment,
|
|
2243
2688
|
serializeCookie,
|
|
2244
2689
|
validatePasswordPolicy
|