@proteinjs/user-server 1.18.0 → 1.19.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.
Files changed (29) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/dist/generated/index.d.ts.map +1 -1
  3. package/dist/generated/index.js +3 -1
  4. package/dist/generated/index.js.map +1 -1
  5. package/dist/src/authorization/UserActivityStamp.d.ts +17 -15
  6. package/dist/src/authorization/UserActivityStamp.d.ts.map +1 -1
  7. package/dist/src/authorization/UserActivityStamp.js +21 -19
  8. package/dist/src/authorization/UserActivityStamp.js.map +1 -1
  9. package/dist/src/authorization/userCache.d.ts +9 -0
  10. package/dist/src/authorization/userCache.d.ts.map +1 -1
  11. package/dist/src/authorization/userCache.js +9 -9
  12. package/dist/src/authorization/userCache.js.map +1 -1
  13. package/dist/src/services/UserPresence.d.ts +16 -0
  14. package/dist/src/services/UserPresence.d.ts.map +1 -0
  15. package/dist/src/services/UserPresence.js +75 -0
  16. package/dist/src/services/UserPresence.js.map +1 -0
  17. package/dist/test/UserActivityStamp.integration.test.js +57 -90
  18. package/dist/test/UserActivityStamp.integration.test.js.map +1 -1
  19. package/dist/test/UserCacheDoesNotStampPresence.integration.test.d.ts +2 -0
  20. package/dist/test/UserCacheDoesNotStampPresence.integration.test.d.ts.map +1 -0
  21. package/dist/test/UserCacheDoesNotStampPresence.integration.test.js +117 -0
  22. package/dist/test/UserCacheDoesNotStampPresence.integration.test.js.map +1 -0
  23. package/generated/index.ts +3 -1
  24. package/package.json +3 -3
  25. package/src/authorization/UserActivityStamp.ts +22 -20
  26. package/src/authorization/userCache.ts +9 -9
  27. package/src/services/UserPresence.ts +26 -0
  28. package/test/UserActivityStamp.integration.test.ts +38 -50
  29. package/test/UserCacheDoesNotStampPresence.integration.test.ts +44 -0
@@ -46,33 +46,35 @@ var logger_1 = require("@proteinjs/logger");
46
46
  var user_1 = require("@proteinjs/user");
47
47
  /**
48
48
  * Writes the LAST-ACTIVITY presence stamp (`user_activity`, one row per user — see
49
- * UserActivityTable's contract): "this human made an interactive request just now".
49
+ * UserActivityTable's contract): "this person gave a page input just now".
50
50
  *
51
- * The TRANSPORT keying lives at the call site — userCache.create runs once per session-cookie
52
- * request (wrapRoute's session-cache build) and only there, so seeded/background contexts
53
- * (runInUserScope sets session data directly) structurally never reach this class. What this
54
- * class owns is the ACCOUNT predicate: machine accounts (`isLoadedFromSource`) are refused —
55
- * their requests do arrive over real sessions (e.g. the error bridge's polling), but a machine
56
- * logging in is not a person being present.
51
+ * The INPUT keying lives at the call site — the UserPresence service is the only caller, and
52
+ * the page reports through it only from a real pointer / key / touch / wheel event. The
53
+ * per-request session build (userCache.create) does NOT call this: it runs for every request
54
+ * over a session cookie, and that transport is what an idle tab produces all day (polls, socket
55
+ * re-joins on reconnect, the reload a deploy pushes) — presence keyed on it read every user as
56
+ * "active today" (founder finding 2026-09-12). What this class owns is the ACCOUNT predicate:
57
+ * the guest identity and machine accounts (`machine` — the one owner of "is this a machine",
58
+ * founder ruling 2026-09-02) are refused, whatever door they arrive through.
57
59
  *
58
60
  * Write behavior mirrors DbSessionStore's touch: throttled per user (a presence fact consumed at
59
- * day grain needs no finer cadence, and an unthrottled stamp would put a write on EVERY request),
60
- * fail-open (a lost stamp is a few minutes of staleness, never a failed request — the returned
61
- * promise NEVER rejects), and race-tolerant (concurrent first stamps contend on the scope-unique
62
- * index; the loser's error is swallowed as debug).
61
+ * day grain needs no finer cadence, and the page already throttles its reports — this is the
62
+ * belt), fail-open (a lost stamp is a few minutes of staleness, never a failed call — the
63
+ * returned promise NEVER rejects), and race-tolerant (concurrent first stamps contend on the
64
+ * scope-unique index; the loser's error is swallowed as debug).
63
65
  */
64
66
  var UserActivityStamp = /** @class */ (function () {
65
67
  function UserActivityStamp() {
66
68
  this.logger = new logger_1.Logger({ name: this.constructor.name });
67
69
  }
68
70
  /**
69
- * Record that `user` is present on an interactive request. Fire-and-forget safe: errors are
70
- * handled (and logged) here, so callers may `void` the returned promise.
71
+ * Record that `user` gave a page human input. Fire-and-forget safe: errors are handled (and
72
+ * logged) here, so callers may `void` the returned promise.
71
73
  */
72
- UserActivityStamp.prototype.recordInteractiveRequest = function (user) {
74
+ UserActivityStamp.prototype.recordHumanInput = function (user) {
73
75
  var _this = this;
74
76
  var _a;
75
- if (!user.id || user.isLoadedFromSource === true) {
77
+ if (!user.id || user.id === user_1.guestUser.id || user.machine === true) {
76
78
  return Promise.resolve();
77
79
  }
78
80
  var last = (_a = UserActivityStamp.lastStampMs.get(user.id)) !== null && _a !== void 0 ? _a : 0;
@@ -85,9 +87,9 @@ var UserActivityStamp = /** @class */ (function () {
85
87
  UserActivityStamp.lastStampMs.clear(); // bounded memory; worst case is one extra stamp per user
86
88
  }
87
89
  return this.upsert(user.id).catch(function (error) {
88
- // Contention (a concurrent request stamped first, racing the scope-unique index) and real
89
- // failures land here alike; both are harmless to the request. Un-throttle so the next
90
- // request retries instead of waiting out a full interval on a stamp that never landed.
90
+ // Contention (a concurrent report stamped first, racing the scope-unique index) and real
91
+ // failures land here alike; both are harmless to the caller. Un-throttle so the next
92
+ // report retries instead of waiting out a full interval on a stamp that never landed.
91
93
  UserActivityStamp.lastStampMs.delete(user.id);
92
94
  _this.logger.error({ message: 'Failed to write user activity stamp', error: error });
93
95
  });
@@ -118,7 +120,7 @@ var UserActivityStamp = /** @class */ (function () {
118
120
  };
119
121
  /** Stamp at most this often per user — same cadence class as DbSessionStore.TOUCH_INTERVAL. */
120
122
  UserActivityStamp.STAMP_INTERVAL_MS = 1000 * 60 * 5;
121
- /** Process-wide: userCache is a plain object, so throttle state can't live per-instance. */
123
+ /** Process-wide: the throttle outlives any one service instance. */
122
124
  UserActivityStamp.lastStampMs = new Map();
123
125
  return UserActivityStamp;
124
126
  }());
@@ -1 +1 @@
1
- {"version":3,"file":"UserActivityStamp.js","sourceRoot":"","sources":["../../../src/authorization/UserActivityStamp.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,kDAA4B;AAC5B,oCAA8C;AAC9C,4CAA2C;AAC3C,wCAAuE;AAEvE;;;;;;;;;;;;;;;;GAgBG;AACH;IAAA;QAMU,WAAM,GAAG,IAAI,eAAM,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC;IAqC/D,CAAC;IAnCC;;;OAGG;IACH,oDAAwB,GAAxB,UAAyB,IAAU;QAAnC,iBAoBC;;QAnBC,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,kBAAkB,KAAK,IAAI,EAAE;YAChD,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;SAC1B;QACD,IAAM,IAAI,GAAG,MAAA,iBAAiB,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,mCAAI,CAAC,CAAC;QAC7D,IAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,IAAI,GAAG,GAAG,IAAI,GAAG,iBAAiB,CAAC,iBAAiB,EAAE;YACpD,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;SAC1B;QACD,iBAAiB,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;QAChD,IAAI,iBAAiB,CAAC,WAAW,CAAC,IAAI,GAAG,KAAK,EAAE;YAC9C,iBAAiB,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC,CAAC,yDAAyD;SACjG;QACD,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,UAAC,KAAK;YACtC,0FAA0F;YAC1F,sFAAsF;YACtF,uFAAuF;YACvF,iBAAiB,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAC9C,KAAI,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,qCAAqC,EAAE,KAAK,OAAA,EAAE,CAAC,CAAC;QAC/E,CAAC,CAAC,CAAC;IACL,CAAC;IAEa,kCAAM,GAApB,UAAqB,MAAc;;;;;;wBAC3B,EAAE,GAAG,IAAA,kBAAa,GAAE,CAAC;wBACV,qBAAM,EAAE,CAAC,GAAG,CAAC,aAAM,CAAC,YAAY,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,EAAA;;wBAA/D,QAAQ,GAAG,SAAoD;6BACjE,QAAQ,EAAR,wBAAQ;wBACV,qBAAM,EAAE,CAAC,MAAM,CAAC,aAAM,CAAC,YAAY,EAAE,EAAE,EAAE,EAAE,QAAQ,CAAC,EAAE,EAAE,YAAY,EAAE,IAAA,gBAAM,GAAE,EAAkB,CAAC,EAAA;;wBAAjG,SAAiG,CAAC;;4BAElG,qBAAM,EAAE,CAAC,MAAM,CAAC,aAAM,CAAC,YAAY,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,IAAA,gBAAM,GAAE,EAAkB,CAAC,EAAA;;wBAA/F,SAA+F,CAAC;;;;;;KAEnG;IAzCD,+FAA+F;IACvE,mCAAiB,GAAG,IAAI,GAAG,EAAE,GAAG,CAAC,AAAhB,CAAiB;IAC1D,4FAA4F;IAC7E,6BAAW,GAAG,IAAI,GAAG,EAAkB,AAA5B,CAA6B;IAuCzD,wBAAC;CAAA,AA3CD,IA2CC;AA3CY,8CAAiB"}
1
+ {"version":3,"file":"UserActivityStamp.js","sourceRoot":"","sources":["../../../src/authorization/UserActivityStamp.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,kDAA4B;AAC5B,oCAA8C;AAC9C,4CAA2C;AAC3C,wCAAkF;AAElF;;;;;;;;;;;;;;;;;;GAkBG;AACH;IAAA;QAMU,WAAM,GAAG,IAAI,eAAM,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC;IAqC/D,CAAC;IAnCC;;;OAGG;IACH,4CAAgB,GAAhB,UAAiB,IAAkC;QAAnD,iBAoBC;;QAnBC,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,EAAE,KAAK,gBAAS,CAAC,EAAE,IAAI,IAAI,CAAC,OAAO,KAAK,IAAI,EAAE;YACjE,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;SAC1B;QACD,IAAM,IAAI,GAAG,MAAA,iBAAiB,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,mCAAI,CAAC,CAAC;QAC7D,IAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,IAAI,GAAG,GAAG,IAAI,GAAG,iBAAiB,CAAC,iBAAiB,EAAE;YACpD,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;SAC1B;QACD,iBAAiB,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;QAChD,IAAI,iBAAiB,CAAC,WAAW,CAAC,IAAI,GAAG,KAAK,EAAE;YAC9C,iBAAiB,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC,CAAC,yDAAyD;SACjG;QACD,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,UAAC,KAAK;YACtC,yFAAyF;YACzF,qFAAqF;YACrF,sFAAsF;YACtF,iBAAiB,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAC9C,KAAI,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,qCAAqC,EAAE,KAAK,OAAA,EAAE,CAAC,CAAC;QAC/E,CAAC,CAAC,CAAC;IACL,CAAC;IAEa,kCAAM,GAApB,UAAqB,MAAc;;;;;;wBAC3B,EAAE,GAAG,IAAA,kBAAa,GAAE,CAAC;wBACV,qBAAM,EAAE,CAAC,GAAG,CAAC,aAAM,CAAC,YAAY,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,EAAA;;wBAA/D,QAAQ,GAAG,SAAoD;6BACjE,QAAQ,EAAR,wBAAQ;wBACV,qBAAM,EAAE,CAAC,MAAM,CAAC,aAAM,CAAC,YAAY,EAAE,EAAE,EAAE,EAAE,QAAQ,CAAC,EAAE,EAAE,YAAY,EAAE,IAAA,gBAAM,GAAE,EAAkB,CAAC,EAAA;;wBAAjG,SAAiG,CAAC;;4BAElG,qBAAM,EAAE,CAAC,MAAM,CAAC,aAAM,CAAC,YAAY,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,IAAA,gBAAM,GAAE,EAAkB,CAAC,EAAA;;wBAA/F,SAA+F,CAAC;;;;;;KAEnG;IAzCD,+FAA+F;IACvE,mCAAiB,GAAG,IAAI,GAAG,EAAE,GAAG,CAAC,AAAhB,CAAiB;IAC1D,oEAAoE;IACrD,6BAAW,GAAG,IAAI,GAAG,EAAkB,AAA5B,CAA6B;IAuCzD,wBAAC;CAAA,AA3CD,IA2CC;AA3CY,8CAAiB"}
@@ -1,4 +1,13 @@
1
1
  import { SessionDataCache } from '@proteinjs/server-api';
2
2
  import { User } from '@proteinjs/user';
3
+ /**
4
+ * The per-request session-cache build: resolves the session's email to the account row every
5
+ * request that rides a session cookie (wrapRoute), and every socket event (util-server's
6
+ * SocketSessionContext). It resolves IDENTITY only — it does not write the presence stamp
7
+ * (`user_activity`, UserActivityTable's contract): this build runs for an idle tab's polls, a
8
+ * socket's room re-joins on every reconnect, the reload a deploy pushes onto every open tab —
9
+ * transport, not a person. Presence is written from the page's human-input report alone
10
+ * (UserPresence.recordPresence).
11
+ */
3
12
  export declare const userCache: SessionDataCache<User>;
4
13
  //# sourceMappingURL=userCache.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"userCache.d.ts","sourceRoot":"","sources":["../../../src/authorization/userCache.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAGzD,OAAO,EAAE,IAAI,EAA6C,MAAM,iBAAiB,CAAC;AAOlF,eAAO,MAAM,SAAS,EAAE,gBAAgB,CAAC,IAAI,CAqD5C,CAAC"}
1
+ {"version":3,"file":"userCache.d.ts","sourceRoot":"","sources":["../../../src/authorization/userCache.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAGzD,OAAO,EAAE,IAAI,EAA6C,MAAM,iBAAiB,CAAC;AAKlF;;;;;;;;GAQG;AACH,eAAO,MAAM,SAAS,EAAE,gBAAgB,CAAC,IAAI,CA8C5C,CAAC"}
@@ -45,9 +45,16 @@ var db_1 = require("@proteinjs/db");
45
45
  var logger_1 = require("@proteinjs/logger");
46
46
  var user_1 = require("@proteinjs/user");
47
47
  var DefaultAdminCredentials_1 = require("../authentication/DefaultAdminCredentials");
48
- var UserActivityStamp_1 = require("./UserActivityStamp");
49
48
  var logger = new logger_1.Logger({ name: 'userCache' });
50
- var userActivityStamp = new UserActivityStamp_1.UserActivityStamp();
49
+ /**
50
+ * The per-request session-cache build: resolves the session's email to the account row every
51
+ * request that rides a session cookie (wrapRoute), and every socket event (util-server's
52
+ * SocketSessionContext). It resolves IDENTITY only — it does not write the presence stamp
53
+ * (`user_activity`, UserActivityTable's contract): this build runs for an idle tab's polls, a
54
+ * socket's room re-joins on every reconnect, the reload a deploy pushes onto every open tab —
55
+ * transport, not a person. Presence is written from the page's human-input report alone
56
+ * (UserPresence.recordPresence).
57
+ */
51
58
  exports.userCache = {
52
59
  key: user_1.USER_SESSION_CACHE_KEY,
53
60
  create: function (sessionId, userEmail) { return __awaiter(void 0, void 0, void 0, function () {
@@ -86,13 +93,6 @@ exports.userCache = {
86
93
  else if (accountUser) {
87
94
  delete accountUser['password'];
88
95
  user = accountUser;
89
- // LAST ACTIVITY (human presence — UserActivityTable's contract): stamped HERE because
90
- // this cache build runs exactly once per session-cookie request (wrapRoute), i.e. only
91
- // for interactive transport. Background/seeded contexts (runInUserScope) set session
92
- // data directly and never pass through, so machinery acting as the user structurally
93
- // cannot stamp; the stamp itself refuses machine accounts. Fire-and-forget: the
94
- // returned promise never rejects, and a request never waits on its own stamp.
95
- void userActivityStamp.recordInteractiveRequest(user);
96
96
  }
97
97
  else {
98
98
  // A session can outlive its account (row deleted, or a dev auto-login for a never-created
@@ -1 +1 @@
1
- {"version":3,"file":"userCache.js","sourceRoot":"","sources":["../../../src/authorization/userCache.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,kDAA4B;AAE5B,oCAA8C;AAC9C,4CAA2C;AAC3C,wCAAkF;AAClF,qFAAoF;AACpF,yDAAwD;AAExD,IAAM,MAAM,GAAG,IAAI,eAAM,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC;AACjD,IAAM,iBAAiB,GAAG,IAAI,qCAAiB,EAAE,CAAC;AAErC,QAAA,SAAS,GAA2B;IAC/C,GAAG,EAAE,6BAAsB;IAC3B,MAAM,EAAE,UAAO,SAAiB,EAAE,SAAiB;;;;;oBAC7C,IAAI,GAAG,gBAAS,CAAC;yBACjB,SAAS,EAAT,wBAAS;oBACL,gBAAgB,GAAG,iDAAuB,CAAC,cAAc,EAAE,CAAC;yBAC9D,CAAA,gBAAgB,IAAI,SAAS,IAAI,gBAAgB,CAAC,QAAQ,CAAA,EAA1D,wBAA0D;oBACtD,SAAS,GAAS;wBACtB,IAAI,EAAE,OAAO;wBACb,KAAK,EAAE,gBAAgB,CAAC,QAAQ;wBAChC,QAAQ,EAAE,gBAAgB,CAAC,QAAQ;wBACnC,aAAa,EAAE,IAAI;wBACnB,KAAK,EAAE,CAAC,OAAO,CAAC;wBAChB,OAAO,EAAE,IAAA,gBAAM,GAAE;wBACjB,OAAO,EAAE,IAAA,gBAAM,GAAE;wBACjB,EAAE,EAAE,OAAO;qBACZ,CAAC;oBACF,IAAI,GAAG,SAAS,CAAC;;wBAEG,qBAAM,IAAA,kBAAa,GAAE,CAAC,GAAG,CAAC,aAAM,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,SAAS,CAAC,WAAW,EAAE,EAAE,CAAC,EAAA;;oBAAxF,WAAW,GAAG,SAA0E;oBAC9F,IAAI,WAAW,IAAI,WAAW,CAAC,MAAM,KAAK,aAAa,EAAE;wBACvD,sFAAsF;wBACtF,iFAAiF;wBACjF,4EAA4E;wBAC5E,MAAM,CAAC,IAAI,CAAC;4BACV,OAAO,EAAE,wEAAwE;4BACjF,GAAG,EAAE,EAAE,SAAS,WAAA,EAAE,SAAS,WAAA,EAAE;yBAC9B,CAAC,CAAC;qBACJ;yBAAM,IAAI,WAAW,EAAE;wBACtB,OAAQ,WAAmB,CAAC,UAAU,CAAC,CAAC;wBACxC,IAAI,GAAG,WAAW,CAAC;wBACnB,sFAAsF;wBACtF,uFAAuF;wBACvF,qFAAqF;wBACrF,qFAAqF;wBACrF,gFAAgF;wBAChF,8EAA8E;wBAC9E,KAAK,iBAAiB,CAAC,wBAAwB,CAAC,IAAI,CAAC,CAAC;qBACvD;yBAAM;wBACL,0FAA0F;wBAC1F,+EAA+E;wBAC/E,sFAAsF;wBACtF,yDAAyD;wBACzD,MAAM,CAAC,IAAI,CAAC;4BACV,OAAO,EAAE,iFAAiF;4BAC1F,GAAG,EAAE,EAAE,SAAS,WAAA,EAAE,SAAS,WAAA,EAAE;yBAC9B,CAAC,CAAC;qBACJ;;wBAIL,sBAAO,IAAI,EAAC;;;SACb;CACF,CAAC"}
1
+ {"version":3,"file":"userCache.js","sourceRoot":"","sources":["../../../src/authorization/userCache.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,kDAA4B;AAE5B,oCAA8C;AAC9C,4CAA2C;AAC3C,wCAAkF;AAClF,qFAAoF;AAEpF,IAAM,MAAM,GAAG,IAAI,eAAM,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC;AAEjD;;;;;;;;GAQG;AACU,QAAA,SAAS,GAA2B;IAC/C,GAAG,EAAE,6BAAsB;IAC3B,MAAM,EAAE,UAAO,SAAiB,EAAE,SAAiB;;;;;oBAC7C,IAAI,GAAG,gBAAS,CAAC;yBACjB,SAAS,EAAT,wBAAS;oBACL,gBAAgB,GAAG,iDAAuB,CAAC,cAAc,EAAE,CAAC;yBAC9D,CAAA,gBAAgB,IAAI,SAAS,IAAI,gBAAgB,CAAC,QAAQ,CAAA,EAA1D,wBAA0D;oBACtD,SAAS,GAAS;wBACtB,IAAI,EAAE,OAAO;wBACb,KAAK,EAAE,gBAAgB,CAAC,QAAQ;wBAChC,QAAQ,EAAE,gBAAgB,CAAC,QAAQ;wBACnC,aAAa,EAAE,IAAI;wBACnB,KAAK,EAAE,CAAC,OAAO,CAAC;wBAChB,OAAO,EAAE,IAAA,gBAAM,GAAE;wBACjB,OAAO,EAAE,IAAA,gBAAM,GAAE;wBACjB,EAAE,EAAE,OAAO;qBACZ,CAAC;oBACF,IAAI,GAAG,SAAS,CAAC;;wBAEG,qBAAM,IAAA,kBAAa,GAAE,CAAC,GAAG,CAAC,aAAM,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,SAAS,CAAC,WAAW,EAAE,EAAE,CAAC,EAAA;;oBAAxF,WAAW,GAAG,SAA0E;oBAC9F,IAAI,WAAW,IAAI,WAAW,CAAC,MAAM,KAAK,aAAa,EAAE;wBACvD,sFAAsF;wBACtF,iFAAiF;wBACjF,4EAA4E;wBAC5E,MAAM,CAAC,IAAI,CAAC;4BACV,OAAO,EAAE,wEAAwE;4BACjF,GAAG,EAAE,EAAE,SAAS,WAAA,EAAE,SAAS,WAAA,EAAE;yBAC9B,CAAC,CAAC;qBACJ;yBAAM,IAAI,WAAW,EAAE;wBACtB,OAAQ,WAAmB,CAAC,UAAU,CAAC,CAAC;wBACxC,IAAI,GAAG,WAAW,CAAC;qBACpB;yBAAM;wBACL,0FAA0F;wBAC1F,+EAA+E;wBAC/E,sFAAsF;wBACtF,yDAAyD;wBACzD,MAAM,CAAC,IAAI,CAAC;4BACV,OAAO,EAAE,iFAAiF;4BAC1F,GAAG,EAAE,EAAE,SAAS,WAAA,EAAE,SAAS,WAAA,EAAE;yBAC9B,CAAC,CAAC;qBACJ;;wBAIL,sBAAO,IAAI,EAAC;;;SACb;CACF,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { Service } from '@proteinjs/service';
2
+ import { UserPresenceService } from '@proteinjs/user';
3
+ /**
4
+ * The server end of the human-input presence door (UserActivityTable's contract): the page
5
+ * reports "a person interacted just now" and this writes the `user_activity` stamp for the
6
+ * CALLING user — the one write path onto presence. Any signed-in user may report their own
7
+ * presence and nobody else's (the user is the session's, never an argument); the guest identity
8
+ * and machine accounts are refused inside the stamp. `doNotAwait`: the page never waits on its
9
+ * own stamp, and a lost stamp is minutes of staleness at day grain, never a failed call.
10
+ */
11
+ export declare class UserPresence implements UserPresenceService {
12
+ serviceMetadata: Service['serviceMetadata'];
13
+ private stamp;
14
+ recordPresence(): Promise<void>;
15
+ }
16
+ //# sourceMappingURL=UserPresence.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UserPresence.d.ts","sourceRoot":"","sources":["../../../src/services/UserPresence.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAAE,mBAAmB,EAAuB,MAAM,iBAAiB,CAAC;AAG3E;;;;;;;GAOG;AACH,qBAAa,YAAa,YAAW,mBAAmB;IAC/C,eAAe,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAKhD;IAEF,OAAO,CAAC,KAAK,CAA2B;IAElC,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;CAGtC"}
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __generator = (this && this.__generator) || function (thisArg, body) {
12
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
13
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
14
+ function verb(n) { return function (v) { return step([n, v]); }; }
15
+ function step(op) {
16
+ if (f) throw new TypeError("Generator is already executing.");
17
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
18
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
19
+ if (y = 0, t) op = [op[0] & 2, t.value];
20
+ switch (op[0]) {
21
+ case 0: case 1: t = op; break;
22
+ case 4: _.label++; return { value: op[1], done: false };
23
+ case 5: _.label++; y = op[1]; op = [0]; continue;
24
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
25
+ default:
26
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
27
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
28
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
29
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
30
+ if (t[2]) _.ops.pop();
31
+ _.trys.pop(); continue;
32
+ }
33
+ op = body.call(thisArg, _);
34
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
35
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
36
+ }
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.UserPresence = void 0;
40
+ var user_1 = require("@proteinjs/user");
41
+ var UserActivityStamp_1 = require("../authorization/UserActivityStamp");
42
+ /**
43
+ * The server end of the human-input presence door (UserActivityTable's contract): the page
44
+ * reports "a person interacted just now" and this writes the `user_activity` stamp for the
45
+ * CALLING user — the one write path onto presence. Any signed-in user may report their own
46
+ * presence and nobody else's (the user is the session's, never an argument); the guest identity
47
+ * and machine accounts are refused inside the stamp. `doNotAwait`: the page never waits on its
48
+ * own stamp, and a lost stamp is minutes of staleness at day grain, never a failed call.
49
+ */
50
+ var UserPresence = /** @class */ (function () {
51
+ function UserPresence() {
52
+ this.serviceMetadata = {
53
+ auth: {
54
+ allUsers: true,
55
+ },
56
+ doNotAwait: true,
57
+ };
58
+ this.stamp = new UserActivityStamp_1.UserActivityStamp();
59
+ }
60
+ UserPresence.prototype.recordPresence = function () {
61
+ return __awaiter(this, void 0, void 0, function () {
62
+ return __generator(this, function (_a) {
63
+ switch (_a.label) {
64
+ case 0: return [4 /*yield*/, this.stamp.recordHumanInput(new user_1.UserRepo().getUser())];
65
+ case 1:
66
+ _a.sent();
67
+ return [2 /*return*/];
68
+ }
69
+ });
70
+ });
71
+ };
72
+ return UserPresence;
73
+ }());
74
+ exports.UserPresence = UserPresence;
75
+ //# sourceMappingURL=UserPresence.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UserPresence.js","sourceRoot":"","sources":["../../../src/services/UserPresence.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,wCAA2E;AAC3E,wEAAuE;AAEvE;;;;;;;GAOG;AACH;IAAA;QACS,oBAAe,GAA+B;YACnD,IAAI,EAAE;gBACJ,QAAQ,EAAE,IAAI;aACf;YACD,UAAU,EAAE,IAAI;SACjB,CAAC;QAEM,UAAK,GAAG,IAAI,qCAAiB,EAAE,CAAC;IAK1C,CAAC;IAHO,qCAAc,GAApB;;;;4BACE,qBAAM,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,IAAI,eAAQ,EAAE,CAAC,OAAO,EAAkC,CAAC,EAAA;;wBAA3F,SAA2F,CAAC;;;;;KAC7F;IACH,mBAAC;AAAD,CAAC,AAbD,IAaC;AAbY,oCAAY"}
@@ -42,8 +42,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
42
42
  var moment_1 = __importDefault(require("moment"));
43
43
  var db_1 = require("@proteinjs/db");
44
44
  var user_1 = require("@proteinjs/user");
45
- var userCache_1 = require("../src/authorization/userCache");
46
45
  var UserActivityStamp_1 = require("../src/authorization/UserActivityStamp");
46
+ var UserPresence_1 = require("../src/services/UserPresence");
47
47
  var UserServerTestEnvironment_1 = require("./UserServerTestEnvironment");
48
48
  var testEnv = new UserServerTestEnvironment_1.UserServerTestEnvironment();
49
49
  var stampInternals = function (stamp) { return stamp.constructor; };
@@ -53,41 +53,15 @@ var activityRows = function (scope) { return __awaiter(void 0, void 0, void 0, f
53
53
  case 1: return [2 /*return*/, _a.sent()];
54
54
  }
55
55
  }); }); };
56
- /** The stamp write is fire-and-forget off userCache — poll the OUTCOME (row present) briefly. */
57
- var waitForActivityRow = function (scope) { return __awaiter(void 0, void 0, void 0, function () {
58
- var attempt, rows;
59
- return __generator(this, function (_a) {
60
- switch (_a.label) {
61
- case 0:
62
- attempt = 0;
63
- _a.label = 1;
64
- case 1:
65
- if (!(attempt < 50)) return [3 /*break*/, 5];
66
- return [4 /*yield*/, activityRows(scope)];
67
- case 2:
68
- rows = _a.sent();
69
- if (rows.length > 0) {
70
- return [2 /*return*/, rows[0]];
71
- }
72
- return [4 /*yield*/, new Promise(function (resolve) { return setTimeout(resolve, 100); })];
73
- case 3:
74
- _a.sent();
75
- _a.label = 4;
76
- case 4:
77
- attempt++;
78
- return [3 /*break*/, 1];
79
- case 5: throw new Error("No user_activity row appeared for scope ".concat(scope));
80
- }
81
- });
82
- }); };
83
56
  /**
84
- * LAST ACTIVITY = HUMAN PRESENCE (UserActivityTable's contract): the stamp fires from
85
- * userCache.create — the once-per-interactive-request session-cache build — and from nowhere
86
- * else. These tests pin the seam's outcomes: a human's request lands the presence row; machine
87
- * accounts (real sessions, e.g. the error bridge's polling login) never do; repeated stamps
88
- * keep ONE row per user; the throttle holds writes to the interval.
57
+ * LAST ACTIVITY = HUMAN PRESENCE (UserActivityTable's contract): the stamp is written from the
58
+ * page's human-input report — the UserPresence service door — and from nowhere else (the
59
+ * session build's non-stamp is pinned in UserCacheDoesNotStampPresence). These tests pin the
60
+ * door's outcomes: a person's report lands the presence row for the CALLING user; machine
61
+ * accounts and the guest identity never do; repeated reports keep ONE row per user; the
62
+ * throttle holds writes to the interval.
89
63
  */
90
- describe('UserActivityStamp — interactive presence', function () {
64
+ describe('UserActivityStamp — human-input presence', function () {
91
65
  beforeAll(function () { return __awaiter(void 0, void 0, void 0, function () {
92
66
  return __generator(this, function (_a) {
93
67
  switch (_a.label) {
@@ -112,26 +86,27 @@ describe('UserActivityStamp — interactive presence', function () {
112
86
  // Each test controls its own throttle history.
113
87
  stampInternals(new UserActivityStamp_1.UserActivityStamp()).lastStampMs.clear();
114
88
  });
115
- it('stamps presence when a signed-in human makes an interactive request (through userCache.create)', function () { return __awaiter(void 0, void 0, void 0, function () {
116
- var user, resolved, row;
89
+ it('the presence door stamps the calling user: a page report under her session lands her row', function () { return __awaiter(void 0, void 0, void 0, function () {
90
+ var user, rows;
117
91
  return __generator(this, function (_a) {
118
92
  switch (_a.label) {
119
93
  case 0: return [4 /*yield*/, testEnv.createUser({ name: 'Present Human', email: 'present-human@test.local' })];
120
94
  case 1:
121
95
  user = _a.sent();
122
- return [4 /*yield*/, userCache_1.userCache.create('interactive-session', user.email)];
96
+ testEnv.actAs(user);
97
+ return [4 /*yield*/, new UserPresence_1.UserPresence().recordPresence()];
123
98
  case 2:
124
- resolved = _a.sent();
125
- expect(resolved.id).toBe(user.id);
126
- return [4 /*yield*/, waitForActivityRow(user.id)];
99
+ _a.sent();
100
+ return [4 /*yield*/, activityRows(user.id)];
127
101
  case 3:
128
- row = _a.sent();
129
- expect((0, moment_1.default)(row.lastActiveAt).isAfter((0, moment_1.default)().subtract(1, 'minute'))).toBe(true);
102
+ rows = _a.sent();
103
+ expect(rows).toHaveLength(1);
104
+ expect((0, moment_1.default)(rows[0].lastActiveAt).isAfter((0, moment_1.default)().subtract(1, 'minute'))).toBe(true);
130
105
  return [2 /*return*/];
131
106
  }
132
107
  });
133
108
  }); });
134
- it('keeps ONE row per user and advances it on later stamps (scope-unique invariant)', function () { return __awaiter(void 0, void 0, void 0, function () {
109
+ it('keeps ONE row per user and advances it on later reports (scope-unique invariant)', function () { return __awaiter(void 0, void 0, void 0, function () {
135
110
  var user, stamp, first, rows;
136
111
  return __generator(this, function (_a) {
137
112
  switch (_a.label) {
@@ -139,18 +114,19 @@ describe('UserActivityStamp — interactive presence', function () {
139
114
  case 1:
140
115
  user = _a.sent();
141
116
  stamp = new UserActivityStamp_1.UserActivityStamp();
142
- return [4 /*yield*/, stamp.recordInteractiveRequest(user)];
117
+ return [4 /*yield*/, stamp.recordHumanInput(user)];
143
118
  case 2:
144
119
  _a.sent();
145
- return [4 /*yield*/, waitForActivityRow(user.id)];
120
+ return [4 /*yield*/, activityRows(user.id)];
146
121
  case 3:
147
- first = _a.sent();
148
- // Clear the throttle so the second request stamps immediately.
122
+ first = (_a.sent())[0];
123
+ expect(first).toBeDefined();
124
+ // Clear the throttle so the second report stamps immediately.
149
125
  stampInternals(stamp).lastStampMs.clear();
150
126
  return [4 /*yield*/, new Promise(function (resolve) { return setTimeout(resolve, 5); })];
151
127
  case 4:
152
128
  _a.sent();
153
- return [4 /*yield*/, stamp.recordInteractiveRequest(user)];
129
+ return [4 /*yield*/, stamp.recordHumanInput(user)];
154
130
  case 5:
155
131
  _a.sent();
156
132
  return [4 /*yield*/, activityRows(user.id)];
@@ -162,8 +138,8 @@ describe('UserActivityStamp — interactive presence', function () {
162
138
  }
163
139
  });
164
140
  }); });
165
- it('never stamps a machine account, even though its requests ride a real session', function () { return __awaiter(void 0, void 0, void 0, function () {
166
- var machine, resolved, _a;
141
+ it('never stamps a machine account (`machine` — the one owner of "is this a machine"), even through the door', function () { return __awaiter(void 0, void 0, void 0, function () {
142
+ var machine, _a;
167
143
  return __generator(this, function (_b) {
168
144
  switch (_b.label) {
169
145
  case 0: return [4 /*yield*/, (0, db_1.getDbAsSystem)().insert(user_1.tables.User, {
@@ -173,32 +149,44 @@ describe('UserActivityStamp — interactive presence', function () {
173
149
  emailVerified: true,
174
150
  roles: [],
175
151
  isLoadedFromSource: true,
152
+ machine: true,
176
153
  })];
177
154
  case 1:
178
155
  machine = _b.sent();
179
- // Await the stamp DIRECTLY (deterministic absence — no fire-and-forget race), then confirm
180
- // the transport seam agrees by resolving the machine session through userCache too.
181
- return [4 /*yield*/, new UserActivityStamp_1.UserActivityStamp().recordInteractiveRequest(machine)];
156
+ return [4 /*yield*/, new UserActivityStamp_1.UserActivityStamp().recordHumanInput(machine)];
182
157
  case 2:
183
- // Await the stamp DIRECTLY (deterministic absence — no fire-and-forget race), then confirm
184
- // the transport seam agrees by resolving the machine session through userCache too.
185
158
  _b.sent();
186
- return [4 /*yield*/, userCache_1.userCache.create('machine-session', machine.email)];
159
+ testEnv.actAs(machine);
160
+ return [4 /*yield*/, new UserPresence_1.UserPresence().recordPresence()];
187
161
  case 3:
188
- resolved = _b.sent();
189
- expect(resolved.id).toBe(machine.id);
190
- return [4 /*yield*/, new Promise(function (resolve) { return setTimeout(resolve, 300); })];
191
- case 4:
192
162
  _b.sent();
193
163
  _a = expect;
194
164
  return [4 /*yield*/, activityRows(machine.id)];
195
- case 5:
165
+ case 4:
196
166
  _a.apply(void 0, [_b.sent()]).toHaveLength(0);
197
167
  return [2 /*return*/];
198
168
  }
199
169
  });
200
170
  }); });
201
- it('throttles: a second request inside the interval writes nothing', function () { return __awaiter(void 0, void 0, void 0, function () {
171
+ it('never stamps the guest identity (a door reached with no signed-in user)', function () { return __awaiter(void 0, void 0, void 0, function () {
172
+ var before, _a;
173
+ return __generator(this, function (_b) {
174
+ switch (_b.label) {
175
+ case 0: return [4 /*yield*/, (0, db_1.getDbAsSystem)().query(user_1.tables.UserActivity, {})];
176
+ case 1:
177
+ before = (_b.sent()).length;
178
+ return [4 /*yield*/, new UserActivityStamp_1.UserActivityStamp().recordHumanInput(user_1.guestUser)];
179
+ case 2:
180
+ _b.sent();
181
+ _a = expect;
182
+ return [4 /*yield*/, (0, db_1.getDbAsSystem)().query(user_1.tables.UserActivity, {})];
183
+ case 3:
184
+ _a.apply(void 0, [(_b.sent()).length]).toBe(before);
185
+ return [2 /*return*/];
186
+ }
187
+ });
188
+ }); });
189
+ it('throttles: a second report inside the interval writes nothing', function () { return __awaiter(void 0, void 0, void 0, function () {
202
190
  var user, stamp, first, rows;
203
191
  return __generator(this, function (_a) {
204
192
  switch (_a.label) {
@@ -206,16 +194,17 @@ describe('UserActivityStamp — interactive presence', function () {
206
194
  case 1:
207
195
  user = _a.sent();
208
196
  stamp = new UserActivityStamp_1.UserActivityStamp();
209
- return [4 /*yield*/, stamp.recordInteractiveRequest(user)];
197
+ return [4 /*yield*/, stamp.recordHumanInput(user)];
210
198
  case 2:
211
199
  _a.sent();
212
- return [4 /*yield*/, waitForActivityRow(user.id)];
200
+ return [4 /*yield*/, activityRows(user.id)];
213
201
  case 3:
214
- first = _a.sent();
215
- // Throttle history now holds this user; a second stamp inside the interval must not write.
216
- return [4 /*yield*/, stamp.recordInteractiveRequest(user)];
202
+ first = (_a.sent())[0];
203
+ expect(first).toBeDefined();
204
+ // Throttle history now holds this user; a second report inside the interval must not write.
205
+ return [4 /*yield*/, stamp.recordHumanInput(user)];
217
206
  case 4:
218
- // Throttle history now holds this user; a second stamp inside the interval must not write.
207
+ // Throttle history now holds this user; a second report inside the interval must not write.
219
208
  _a.sent();
220
209
  return [4 /*yield*/, new Promise(function (resolve) { return setTimeout(resolve, 300); })];
221
210
  case 5:
@@ -229,27 +218,5 @@ describe('UserActivityStamp — interactive presence', function () {
229
218
  }
230
219
  });
231
220
  }); });
232
- it('a session for a missing account still resolves guest and stamps nothing (no throw)', function () { return __awaiter(void 0, void 0, void 0, function () {
233
- var before, resolved, _a;
234
- return __generator(this, function (_b) {
235
- switch (_b.label) {
236
- case 0: return [4 /*yield*/, (0, db_1.getDbAsSystem)().query(user_1.tables.UserActivity, {})];
237
- case 1:
238
- before = (_b.sent()).length;
239
- return [4 /*yield*/, userCache_1.userCache.create('stale-session', 'no-such-account@test.local')];
240
- case 2:
241
- resolved = _b.sent();
242
- expect(resolved.id).toBe('guest');
243
- return [4 /*yield*/, new Promise(function (resolve) { return setTimeout(resolve, 200); })];
244
- case 3:
245
- _b.sent();
246
- _a = expect;
247
- return [4 /*yield*/, (0, db_1.getDbAsSystem)().query(user_1.tables.UserActivity, {})];
248
- case 4:
249
- _a.apply(void 0, [(_b.sent()).length]).toBe(before);
250
- return [2 /*return*/];
251
- }
252
- });
253
- }); });
254
221
  });
255
222
  //# sourceMappingURL=UserActivityStamp.integration.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"UserActivityStamp.integration.test.js","sourceRoot":"","sources":["../../test/UserActivityStamp.integration.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"UserActivityStamp.integration.test.js","sourceRoot":"","sources":["../../test/UserActivityStamp.integration.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=UserCacheDoesNotStampPresence.integration.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UserCacheDoesNotStampPresence.integration.test.d.ts","sourceRoot":"","sources":["../../test/UserCacheDoesNotStampPresence.integration.test.ts"],"names":[],"mappings":""}