mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-23 07:26:30 +00:00
refactor(db): TrekRepository base — every repository path validates the request context and reads bypass the identity map by default
This commit is contained in:
@@ -35,7 +35,7 @@ import { extractToken, verifyJwtAndLoadUser } from './jwt-verify';
|
||||
* `@mikro-orm/nestjs`'s provider factory injects `orm.em`, the ORM's single
|
||||
* GLOBAL, context-resolving `EntityManager`, the same object every request
|
||||
* shares. It resolves to the request's transactional fork at QUERY TIME:
|
||||
* `EntityRepository.getRepository` builds the repository holding a
|
||||
* `EntityManager.getRepository` builds the repository holding a
|
||||
* reference to `this.em` with no `getContext()` call, and
|
||||
* `EntityRepository.findOne` calls `this.getEntityManager().findOne(...)`,
|
||||
* which resolves the live `AsyncLocalStorage`/`TransactionContext` inside
|
||||
|
||||
@@ -38,6 +38,30 @@
|
||||
* deviation, not a bug — never widen the regex to `/^(0|[1-9]\d*)$/` or any
|
||||
* other shape that would reject `'007'`, and never widen it to accept the
|
||||
* divergent shapes above either.
|
||||
*
|
||||
* **The "accepted narrowing" is a different SIZE depending on what the
|
||||
* legacy seam bound (task-3-rereview.md R1).** Not every legacy raw-SQL
|
||||
* call site bound the route string straight into `WHERE id = ?` and leaned
|
||||
* on SQLite's affinity as described above (an "affinity seam" —
|
||||
* `registration-invites.service.ts::deleteInvite` is one, and so are the
|
||||
* categories/tags/token routes Task 2 converted): some called `Number(id)`
|
||||
* FIRST, in application code, before the query ever ran (a "`Number()`
|
||||
* seam" — `passkey.service.ts::renamePasskey`/`deletePasskey`,
|
||||
* `AdminService.resetUserPasskeys`). On an affinity seam, `toRowId` removes
|
||||
* only the genuine false-accepts described above (whitespace, decimal
|
||||
* point, exponent, leading `+`). On a `Number()` seam it removes a WIDER
|
||||
* set: `Number('0x10')`, `Number('1e1')`, `Number('16.0')` and `Number('
|
||||
* 16')` all coerce to a real integer in JavaScript (unlike SQLite's
|
||||
* affinity, which never converts a hex literal), so on that kind of seam
|
||||
* `toRowId` additionally refuses every hex and exponent form that used to
|
||||
* hit a REAL row, not just malformed ones. Both are the same deliberate,
|
||||
* accepted deviation — `toRowId` is right for both — but a regression test
|
||||
* that asserts "`'0x10'` gets the legacy 404" is only true on an affinity
|
||||
* seam; on a `Number()` seam the legacy statement acted on the row `toRowId`
|
||||
* now refuses, so the honest claim is "the deliberate `toRowId` narrowing",
|
||||
* not "parity with the legacy". Check which kind of seam a route's legacy
|
||||
* handler was (`git show <base>:<file>` on the actual statement, not the
|
||||
* route) before writing that test.
|
||||
*/
|
||||
export function toRowId(value: unknown): number | null {
|
||||
if (typeof value === 'number') {
|
||||
|
||||
@@ -146,38 +146,6 @@ export function redirectUriMatches(allowed: string, requested: string): boolean
|
||||
&& a.password === r.password;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// DB row types
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
export interface OAuthClientRow {
|
||||
id: string;
|
||||
user_id: number;
|
||||
name: string;
|
||||
client_id: string;
|
||||
client_secret_hash: string;
|
||||
redirect_uris: string; // JSON array
|
||||
allowed_scopes: string; // JSON array
|
||||
created_at: string;
|
||||
is_public: number; // 0 | 1 (SQLite boolean)
|
||||
created_via: string; // 'settings_ui' | 'browser-registration'
|
||||
allows_client_credentials: number; // 0 | 1
|
||||
}
|
||||
|
||||
export interface OAuthTokenRow {
|
||||
id: number;
|
||||
client_id: string;
|
||||
user_id: number;
|
||||
access_token_hash: string;
|
||||
refresh_token_hash: string;
|
||||
scopes: string; // JSON array
|
||||
audience: string | null;
|
||||
access_token_expires_at: string;
|
||||
refresh_token_expires_at: string;
|
||||
revoked_at: string | null;
|
||||
parent_token_id: number | null;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Token helpers
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user