@fonderie/auth 7.6.1 → 7.7.1
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/index.cjs +36 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +36 -2
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
package/dist/index.cjs
CHANGED
|
@@ -1048,13 +1048,23 @@ var MAX_HISTORY_LIMIT = 200;
|
|
|
1048
1048
|
|
|
1049
1049
|
// src/services/request-meta.ts
|
|
1050
1050
|
var UA_MAX = 512;
|
|
1051
|
+
var warnedAboutMissingIdentity = false;
|
|
1052
|
+
function warnIfIdentityless(ctx) {
|
|
1053
|
+
if (warnedAboutMissingIdentity) return;
|
|
1054
|
+
warnedAboutMissingIdentity = true;
|
|
1055
|
+
console.warn(
|
|
1056
|
+
`[auth] recording a security event with no client IP and no user-agent for ${ctx.request.method} ${new URL(ctx.request.url).pathname}. Login history and session rows will show "Unknown device" with no IP for these. This is what a hand-built request looks like: if you call fonderie.handle() directly, forward the caller's user-agent header and pass the resolved IP as \`handle(req, { meta: { clientIp } })\` \u2014 resolve it with resolveClientIp from @fonderie/core/middlewares rather than reading the socket, or a proxied deployment records the proxy. Reported once per process.`
|
|
1057
|
+
);
|
|
1058
|
+
}
|
|
1051
1059
|
function requestMeta(ctx) {
|
|
1052
1060
|
const ip = ctx.meta["clientIp"];
|
|
1053
1061
|
const ua = ctx.request.headers.get("user-agent");
|
|
1054
|
-
|
|
1062
|
+
const meta = {
|
|
1055
1063
|
ipAddress: typeof ip === "string" && ip.length > 0 ? ip : null,
|
|
1056
1064
|
userAgent: ua && ua.length > 0 ? ua.slice(0, UA_MAX) : null
|
|
1057
1065
|
};
|
|
1066
|
+
if (meta.ipAddress === null && meta.userAgent === null) warnIfIdentityless(ctx);
|
|
1067
|
+
return meta;
|
|
1058
1068
|
}
|
|
1059
1069
|
|
|
1060
1070
|
// src/controllers/mfa.controller.ts
|
|
@@ -1900,12 +1910,29 @@ function authController(store, config, bus) {
|
|
|
1900
1910
|
}
|
|
1901
1911
|
const pin = raw.trim();
|
|
1902
1912
|
if (ctx.user.loginMethod === "phone") {
|
|
1913
|
+
const phoneMeta = requestMeta(ctx);
|
|
1903
1914
|
const record = await phoneVerif.findByUser(ctx.user.id, pin);
|
|
1904
1915
|
if (!record) {
|
|
1916
|
+
await loginEvents.recordSafe({
|
|
1917
|
+
userId: ctx.user.id,
|
|
1918
|
+
emailAttempted: null,
|
|
1919
|
+
method: "phone",
|
|
1920
|
+
outcome: "failed",
|
|
1921
|
+
failureReason: "invalid_pin",
|
|
1922
|
+
...phoneMeta
|
|
1923
|
+
});
|
|
1905
1924
|
return (0, import_core6.setApiResponse)(import_core6.HTTP.BAD_REQUEST, "VERIFICATION_FAILED", "Invalid or expired pin");
|
|
1906
1925
|
}
|
|
1907
1926
|
if (/* @__PURE__ */ new Date() > record.expiresAt) {
|
|
1908
1927
|
await phoneVerif.deleteByUser(ctx.user.id);
|
|
1928
|
+
await loginEvents.recordSafe({
|
|
1929
|
+
userId: ctx.user.id,
|
|
1930
|
+
emailAttempted: null,
|
|
1931
|
+
method: "phone",
|
|
1932
|
+
outcome: "failed",
|
|
1933
|
+
failureReason: "expired_pin",
|
|
1934
|
+
...phoneMeta
|
|
1935
|
+
});
|
|
1909
1936
|
return (0, import_core6.setApiResponse)(
|
|
1910
1937
|
import_core6.HTTP.BAD_REQUEST,
|
|
1911
1938
|
"VERIFICATION_FAILED",
|
|
@@ -1917,7 +1944,14 @@ function authController(store, config, bus) {
|
|
|
1917
1944
|
loginMethod: "phone",
|
|
1918
1945
|
phoneVerified: true
|
|
1919
1946
|
});
|
|
1920
|
-
await sessions.create(ctx.user.id, refreshToken, refreshTokenExpiry(refreshToken), sid,
|
|
1947
|
+
await sessions.create(ctx.user.id, refreshToken, refreshTokenExpiry(refreshToken), sid, phoneMeta);
|
|
1948
|
+
await loginEvents.recordSafe({
|
|
1949
|
+
userId: ctx.user.id,
|
|
1950
|
+
emailAttempted: null,
|
|
1951
|
+
method: "phone",
|
|
1952
|
+
outcome: "success",
|
|
1953
|
+
...phoneMeta
|
|
1954
|
+
});
|
|
1921
1955
|
const verifiedUser = await users.findById(ctx.user.id);
|
|
1922
1956
|
if (!verifiedUser) {
|
|
1923
1957
|
return (0, import_core6.setApiResponse)(import_core6.HTTP.NOT_FOUND, "NOT_FOUND", "User not found");
|