@fonderie/auth 7.6.1 → 7.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/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 +1 -1
package/dist/index.js
CHANGED
|
@@ -1008,13 +1008,23 @@ var MAX_HISTORY_LIMIT = 200;
|
|
|
1008
1008
|
|
|
1009
1009
|
// src/services/request-meta.ts
|
|
1010
1010
|
var UA_MAX = 512;
|
|
1011
|
+
var warnedAboutMissingIdentity = false;
|
|
1012
|
+
function warnIfIdentityless(ctx) {
|
|
1013
|
+
if (warnedAboutMissingIdentity) return;
|
|
1014
|
+
warnedAboutMissingIdentity = true;
|
|
1015
|
+
console.warn(
|
|
1016
|
+
`[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.`
|
|
1017
|
+
);
|
|
1018
|
+
}
|
|
1011
1019
|
function requestMeta(ctx) {
|
|
1012
1020
|
const ip = ctx.meta["clientIp"];
|
|
1013
1021
|
const ua = ctx.request.headers.get("user-agent");
|
|
1014
|
-
|
|
1022
|
+
const meta = {
|
|
1015
1023
|
ipAddress: typeof ip === "string" && ip.length > 0 ? ip : null,
|
|
1016
1024
|
userAgent: ua && ua.length > 0 ? ua.slice(0, UA_MAX) : null
|
|
1017
1025
|
};
|
|
1026
|
+
if (meta.ipAddress === null && meta.userAgent === null) warnIfIdentityless(ctx);
|
|
1027
|
+
return meta;
|
|
1018
1028
|
}
|
|
1019
1029
|
|
|
1020
1030
|
// src/controllers/mfa.controller.ts
|
|
@@ -1860,12 +1870,29 @@ function authController(store, config, bus) {
|
|
|
1860
1870
|
}
|
|
1861
1871
|
const pin = raw.trim();
|
|
1862
1872
|
if (ctx.user.loginMethod === "phone") {
|
|
1873
|
+
const phoneMeta = requestMeta(ctx);
|
|
1863
1874
|
const record = await phoneVerif.findByUser(ctx.user.id, pin);
|
|
1864
1875
|
if (!record) {
|
|
1876
|
+
await loginEvents.recordSafe({
|
|
1877
|
+
userId: ctx.user.id,
|
|
1878
|
+
emailAttempted: null,
|
|
1879
|
+
method: "phone",
|
|
1880
|
+
outcome: "failed",
|
|
1881
|
+
failureReason: "invalid_pin",
|
|
1882
|
+
...phoneMeta
|
|
1883
|
+
});
|
|
1865
1884
|
return setApiResponse3(HTTP3.BAD_REQUEST, "VERIFICATION_FAILED", "Invalid or expired pin");
|
|
1866
1885
|
}
|
|
1867
1886
|
if (/* @__PURE__ */ new Date() > record.expiresAt) {
|
|
1868
1887
|
await phoneVerif.deleteByUser(ctx.user.id);
|
|
1888
|
+
await loginEvents.recordSafe({
|
|
1889
|
+
userId: ctx.user.id,
|
|
1890
|
+
emailAttempted: null,
|
|
1891
|
+
method: "phone",
|
|
1892
|
+
outcome: "failed",
|
|
1893
|
+
failureReason: "expired_pin",
|
|
1894
|
+
...phoneMeta
|
|
1895
|
+
});
|
|
1869
1896
|
return setApiResponse3(
|
|
1870
1897
|
HTTP3.BAD_REQUEST,
|
|
1871
1898
|
"VERIFICATION_FAILED",
|
|
@@ -1877,7 +1904,14 @@ function authController(store, config, bus) {
|
|
|
1877
1904
|
loginMethod: "phone",
|
|
1878
1905
|
phoneVerified: true
|
|
1879
1906
|
});
|
|
1880
|
-
await sessions.create(ctx.user.id, refreshToken, refreshTokenExpiry(refreshToken), sid,
|
|
1907
|
+
await sessions.create(ctx.user.id, refreshToken, refreshTokenExpiry(refreshToken), sid, phoneMeta);
|
|
1908
|
+
await loginEvents.recordSafe({
|
|
1909
|
+
userId: ctx.user.id,
|
|
1910
|
+
emailAttempted: null,
|
|
1911
|
+
method: "phone",
|
|
1912
|
+
outcome: "success",
|
|
1913
|
+
...phoneMeta
|
|
1914
|
+
});
|
|
1881
1915
|
const verifiedUser = await users.findById(ctx.user.id);
|
|
1882
1916
|
if (!verifiedUser) {
|
|
1883
1917
|
return setApiResponse3(HTTP3.NOT_FOUND, "NOT_FOUND", "User not found");
|