@linkforty/core 1.20.1 → 1.21.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.
@@ -5,6 +5,7 @@ import { parseUserAgent, getLocationFromIP, buildRedirectUrl, detectDevice } fro
5
5
  import { storeFingerprintForClick } from '../lib/fingerprint.js';
6
6
  import { emitClickEvent } from '../lib/event-emitter.js';
7
7
  import { classifyBot, edgeBotSignal } from '../lib/bot-detection.js';
8
+ import { evaluateLinkSafety, generateWarningLinkHTML, createOwnerSuspensionSelect, } from '../lib/link-safety.js';
8
9
  /**
9
10
  * Detect iOS in-app browsers where Universal Links don't fire.
10
11
  * These browsers use WKWebView which bypasses the Universal Links mechanism.
@@ -127,7 +128,36 @@ function generateInterstitialHTML(schemeUrl, fallbackUrl, title) {
127
128
  </script>
128
129
  </body></html>`;
129
130
  }
130
- export async function redirectRoutes(fastify) {
131
+ export async function redirectRoutes(fastify, options = {}) {
132
+ /**
133
+ * Owner-restriction support is detected rather than assumed.
134
+ *
135
+ * The redirect query joins `organizations` for settings, and that table is now
136
+ * created by this package (#35) — before that fix a stock self-hosted install
137
+ * 500'd on every redirect with 42P01, which made this probe's guarantee hollow:
138
+ * it guarded the column while the table itself was missing.
139
+ *
140
+ * The column still needs probing separately, because `suspended_at` is added by
141
+ * downstream consumers that model owner restriction rather than by this package.
142
+ * Probing once and building the SELECT accordingly avoids failing every redirect
143
+ * on a missing column.
144
+ *
145
+ * Scoped to this registration rather than the module: module-level state would
146
+ * be shared by every createServer() in the process, so two servers pointed at
147
+ * different databases would share whichever answer landed first — and it forced
148
+ * a test-only reset export onto the package's public API.
149
+ *
150
+ * The in-flight promise is memoised, not just its result, so N concurrent cold
151
+ * requests issue one probe rather than N.
152
+ *
153
+ * Probed lazily because the database may not be reachable at registration time.
154
+ * A probe failure is treated as "unsupported", so it can never take the redirect
155
+ * path down.
156
+ */
157
+ const resolveOwnerSuspensionSelect = createOwnerSuspensionSelect({
158
+ query: (sql) => db.query(sql),
159
+ onSupported: () => fastify.log.info('Redirect: owner restriction supported (organizations.suspended_at present)'),
160
+ });
131
161
  // Helper function to handle the actual redirect logic
132
162
  async function handleRedirect(request, reply, shortCode, templateSlug) {
133
163
  let linkData = null;
@@ -146,11 +176,13 @@ export async function redirectRoutes(fastify) {
146
176
  // Build query based on whether template slug is provided
147
177
  let query;
148
178
  let params;
179
+ const ownerSuspensionColumn = await resolveOwnerSuspensionSelect();
149
180
  if (templateSlug) {
150
181
  // Template-based URL: verify both template and link match
151
182
  // Also fetch template settings and org settings for URL fallback chain
152
183
  query = `
153
184
  SELECT l.*, t.settings AS template_settings, o.settings AS org_settings
185
+ ${ownerSuspensionColumn}
154
186
  FROM links l
155
187
  LEFT JOIN link_templates t ON l.template_id = t.id
156
188
  LEFT JOIN organizations o ON l.organization_id = o.id
@@ -165,6 +197,7 @@ export async function redirectRoutes(fastify) {
165
197
  // Also fetch template settings and org settings for URL fallback chain
166
198
  query = `
167
199
  SELECT l.*, t.settings AS template_settings, o.settings AS org_settings
200
+ ${ownerSuspensionColumn}
168
201
  FROM links l
169
202
  LEFT JOIN link_templates t ON l.template_id = t.id
170
203
  LEFT JOIN organizations o ON l.organization_id = o.id
@@ -189,6 +222,38 @@ export async function redirectRoutes(fastify) {
189
222
  }
190
223
  }
191
224
  const link = JSON.parse(linkData);
225
+ // Safety gate, applied after the cache read so it covers cached rows too.
226
+ //
227
+ // It does NOT close the stale-cache window on its own, and an earlier version
228
+ // of this comment wrongly claimed it did: a cached row carries the value of
229
+ // `is_active` as at cache time, so reading it here sees the same stale `true`
230
+ // the old code did. Staleness is handled by invalidateLinkResolutionCache(),
231
+ // called when a link is updated or deleted.
232
+ //
233
+ // `is_active` therefore stays filtered in SQL — an inactive link never needs
234
+ // fetching or caching. What genuinely cannot be expressed in the WHERE clause
235
+ // is `warn_at`, which needs the row in hand to choose between redirecting and
236
+ // serving an interstitial.
237
+ const safety = evaluateLinkSafety({
238
+ isActive: link.is_active,
239
+ warnAt: link.warn_at,
240
+ ownerSuspendedAt: link.owner_suspended_at,
241
+ });
242
+ if (safety === 'block') {
243
+ // Same response as an unknown code — see evaluateLinkSafety for why.
244
+ return reply.status(404).send({ error: 'Link not found' });
245
+ }
246
+ if (safety === 'warn') {
247
+ // No click is recorded here. A warning view is not a click on the link, and
248
+ // counting it would silently inflate the owner's analytics.
249
+ const destination = link.original_url || link.web_fallback_url || link.deep_link_path || '';
250
+ return reply
251
+ .status(200)
252
+ .header('X-Robots-Tag', 'noindex, nofollow')
253
+ .header('Cache-Control', 'no-store')
254
+ .type('text/html')
255
+ .send(generateWarningLinkHTML(destination, { reportUrl: options?.abuseReportUrl }));
256
+ }
192
257
  // Check targeting rules BEFORE redirecting
193
258
  if (link.targeting_rules) {
194
259
  const userAgent = request.headers['user-agent'] || '';
@@ -1 +1 @@
1
- {"version":3,"file":"redirect.js","sourceRoot":"","sources":["../../src/routes/redirect.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"redirect.js","sourceRoot":"","sources":["../../src/routes/redirect.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=redirect.safety.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redirect.safety.test.d.ts","sourceRoot":"","sources":["../../src/routes/redirect.safety.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,181 @@
1
+ /**
2
+ * Route-level tests for the link safety gate.
3
+ *
4
+ * These drive the real `redirectRoutes` plugin through fastify.inject(), with only
5
+ * the data layer mocked. The unit tests in lib/link-safety.test.ts already cover
6
+ * the decision table; what matters here is the behaviour a visitor actually gets:
7
+ * status codes, headers, whether a 302 happens, and whether a click is recorded.
8
+ */
9
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
10
+ import Fastify from 'fastify';
11
+ // vi.mock is hoisted above these imports, so redirect.js still receives the mock.
12
+ import { redirectRoutes } from './redirect.js';
13
+ const query = vi.fn();
14
+ vi.mock('../lib/database.js', () => ({
15
+ db: {
16
+ query: (...args) => query(...args),
17
+ },
18
+ }));
19
+ /** A resolved link row as the redirect query would return it. */
20
+ function linkRow(overrides = {}) {
21
+ return {
22
+ id: '00000000-0000-0000-0000-0000000000aa',
23
+ short_code: 'abc123',
24
+ original_url: 'https://example.com/landing',
25
+ web_fallback_url: null,
26
+ deep_link_path: null,
27
+ is_active: true,
28
+ warn_at: null,
29
+ owner_suspended_at: null,
30
+ expires_at: null,
31
+ targeting_rules: null,
32
+ template_settings: null,
33
+ org_settings: null,
34
+ utm_parameters: null,
35
+ append_click_id: false,
36
+ ...overrides,
37
+ };
38
+ }
39
+ /**
40
+ * @param row the link the lookup resolves to, or null for "not found"
41
+ * @param suspensionColumn whether organizations.suspended_at exists in this database
42
+ */
43
+ function mockDb(row, suspensionColumn = true) {
44
+ query.mockReset();
45
+ query.mockImplementation(async (sql) => {
46
+ if (/information_schema\.columns/i.test(sql)) {
47
+ return { rows: suspensionColumn ? [{ '?column?': 1 }] : [], rowCount: suspensionColumn ? 1 : 0 };
48
+ }
49
+ if (/^\s*SELECT\s+l\.\*/i.test(sql) || /FROM links l/i.test(sql)) {
50
+ return { rows: row ? [row] : [], rowCount: row ? 1 : 0 };
51
+ }
52
+ // click inserts, anything else
53
+ return { rows: [], rowCount: 0 };
54
+ });
55
+ }
56
+ /** Did any click get written? Flushes the setImmediate the redirect uses. */
57
+ async function clickWasRecorded() {
58
+ await new Promise((r) => setImmediate(r));
59
+ return query.mock.calls.some(([sql]) => /INSERT INTO click_events/i.test(String(sql)));
60
+ }
61
+ let app;
62
+ beforeEach(async () => {
63
+ // No probe reset needed: the probe is scoped to each registration, so a fresh
64
+ // Fastify instance per test gets a fresh probe. That the reset export is gone is
65
+ // the point — it existed only to work around module-global state.
66
+ app = Fastify();
67
+ await app.register(redirectRoutes, { abuseReportUrl: 'https://example.org/abuse' });
68
+ await app.ready();
69
+ });
70
+ afterEach(async () => {
71
+ // Click recording is fire-and-forget (setImmediate). Let any pending insert from
72
+ // this test finish BEFORE the next test resets the mock, otherwise a stray click
73
+ // from a previous redirect lands in the next test's call log and looks like a bug.
74
+ await new Promise((r) => setImmediate(r));
75
+ await app.close();
76
+ });
77
+ describe('redirect safety gate', () => {
78
+ it('redirects a healthy link', async () => {
79
+ mockDb(linkRow());
80
+ const res = await app.inject({ method: 'GET', url: '/abc123' });
81
+ expect(res.statusCode).toBe(302);
82
+ expect(res.headers.location).toBe('https://example.com/landing');
83
+ });
84
+ it('404s an inactive link', async () => {
85
+ mockDb(linkRow({ is_active: false }));
86
+ const res = await app.inject({ method: 'GET', url: '/abc123' });
87
+ expect(res.statusCode).toBe(404);
88
+ });
89
+ it('404s when the owner is restricted, even though the link itself is fine', async () => {
90
+ mockDb(linkRow({ owner_suspended_at: '2026-08-10T00:00:00Z' }));
91
+ const res = await app.inject({ method: 'GET', url: '/abc123' });
92
+ expect(res.statusCode).toBe(404);
93
+ });
94
+ it('gives a restricted owner the SAME response as an unknown code, leaking nothing', async () => {
95
+ mockDb(linkRow({ owner_suspended_at: '2026-08-10T00:00:00Z' }));
96
+ const restricted = await app.inject({ method: 'GET', url: '/abc123' });
97
+ mockDb(null);
98
+ const unknown = await app.inject({ method: 'GET', url: '/nosuchcode' });
99
+ expect(restricted.statusCode).toBe(unknown.statusCode);
100
+ expect(restricted.body).toBe(unknown.body);
101
+ });
102
+ describe('a link flagged to warn', () => {
103
+ it('serves an interstitial instead of redirecting', async () => {
104
+ mockDb(linkRow({ warn_at: '2026-08-10T00:00:00Z' }));
105
+ const res = await app.inject({ method: 'GET', url: '/abc123' });
106
+ expect(res.statusCode).toBe(200);
107
+ expect(res.statusCode).not.toBe(302);
108
+ expect(res.headers['content-type']).toMatch(/text\/html/);
109
+ expect(res.body).toContain('Check this link before continuing');
110
+ });
111
+ it('shows the destination the short link was hiding', async () => {
112
+ mockDb(linkRow({ warn_at: '2026-08-10T00:00:00Z' }));
113
+ const res = await app.inject({ method: 'GET', url: '/abc123' });
114
+ expect(res.body).toContain('https://example.com/landing');
115
+ });
116
+ it('asks not to be indexed or cached', async () => {
117
+ mockDb(linkRow({ warn_at: '2026-08-10T00:00:00Z' }));
118
+ const res = await app.inject({ method: 'GET', url: '/abc123' });
119
+ expect(res.headers['x-robots-tag']).toMatch(/noindex/);
120
+ expect(res.headers['cache-control']).toMatch(/no-store/);
121
+ });
122
+ it('links to the configured reporting page', async () => {
123
+ mockDb(linkRow({ warn_at: '2026-08-10T00:00:00Z' }));
124
+ const res = await app.inject({ method: 'GET', url: '/abc123' });
125
+ expect(res.body).toContain('https://example.org/abuse');
126
+ });
127
+ it('records NO click — a warning view is not a click on the link', async () => {
128
+ mockDb(linkRow({ warn_at: '2026-08-10T00:00:00Z' }));
129
+ await app.inject({ method: 'GET', url: '/abc123' });
130
+ expect(await clickWasRecorded()).toBe(false);
131
+ });
132
+ it('falls back to the web fallback url when there is no original url', async () => {
133
+ mockDb(linkRow({ warn_at: '2026-08-10T00:00:00Z', original_url: '', web_fallback_url: 'https://example.net/x' }));
134
+ const res = await app.inject({ method: 'GET', url: '/abc123' });
135
+ expect(res.body).toContain('https://example.net/x');
136
+ });
137
+ it('is outranked by owner restriction', async () => {
138
+ mockDb(linkRow({ warn_at: '2026-08-10T00:00:00Z', owner_suspended_at: '2026-08-10T00:00:00Z' }));
139
+ const res = await app.inject({ method: 'GET', url: '/abc123' });
140
+ expect(res.statusCode).toBe(404);
141
+ });
142
+ });
143
+ describe('a database without organizations.suspended_at', () => {
144
+ it('still resolves links normally rather than erroring', async () => {
145
+ mockDb(linkRow(), /* suspensionColumn */ false);
146
+ const res = await app.inject({ method: 'GET', url: '/abc123' });
147
+ expect(res.statusCode).toBe(302);
148
+ });
149
+ it('never asks for the column it just proved absent', async () => {
150
+ mockDb(linkRow(), false);
151
+ await app.inject({ method: 'GET', url: '/abc123' });
152
+ const lookups = query.mock.calls
153
+ .map(([sql]) => String(sql))
154
+ .filter((sql) => /FROM links l/i.test(sql));
155
+ expect(lookups.length).toBeGreaterThan(0);
156
+ for (const sql of lookups)
157
+ expect(sql).not.toMatch(/owner_suspended_at/);
158
+ });
159
+ it('probes once even under CONCURRENT cold requests', async () => {
160
+ // The sequential test below passes trivially because inject() awaits. This one
161
+ // fires them together, which is what the memoised promise actually buys.
162
+ mockDb(linkRow(), false);
163
+ await Promise.all([
164
+ app.inject({ method: 'GET', url: '/abc123' }),
165
+ app.inject({ method: 'GET', url: '/abc123' }),
166
+ app.inject({ method: 'GET', url: '/abc123' }),
167
+ app.inject({ method: 'GET', url: '/abc123' }),
168
+ ]);
169
+ const probes = query.mock.calls.filter(([sql]) => /information_schema\.columns/i.test(String(sql)));
170
+ expect(probes).toHaveLength(1);
171
+ });
172
+ it('probes only once across sequential requests', async () => {
173
+ mockDb(linkRow(), false);
174
+ await app.inject({ method: 'GET', url: '/abc123' });
175
+ await app.inject({ method: 'GET', url: '/abc123' });
176
+ const probes = query.mock.calls.filter(([sql]) => /information_schema\.columns/i.test(String(sql)));
177
+ expect(probes).toHaveLength(1);
178
+ });
179
+ });
180
+ });
181
+ //# sourceMappingURL=redirect.safety.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redirect.safety.test.js","sourceRoot":"","sources":["../../src/routes/redirect.safety.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=sdk-cache-bypass.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sdk-cache-bypass.test.d.ts","sourceRoot":"","sources":["../../src/routes/sdk-cache-bypass.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,167 @@
1
+ /**
2
+ * Regression test for the owner-restriction bypass via the SDK resolve endpoint.
3
+ *
4
+ * The redirect and `/api/sdk/v1/resolve/:shortCode` write the SAME Redis key. The SDK
5
+ * query used to omit the `organizations` join, so the row it cached carried no
6
+ * `owner_suspended_at`. The redirect then read `undefined`, its gate treated that as
7
+ * "not restricted", and a restricted owner's link redirected for the rest of the TTL.
8
+ *
9
+ * Both plugins share one fake Redis here, because sharing the cache is the mechanism —
10
+ * testing them in isolation cannot reproduce it.
11
+ */
12
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
13
+ import Fastify from 'fastify';
14
+ const query = vi.fn();
15
+ vi.mock('../lib/database.js', () => ({ db: { query: (...a) => query(...a) } }));
16
+ import { redirectRoutes } from './redirect.js';
17
+ import { sdkRoutes } from './sdk.js';
18
+ /** Minimal shared Redis stand-in — get/set/setex/del over one Map. */
19
+ function fakeRedis() {
20
+ const store = new Map();
21
+ return {
22
+ store,
23
+ get: async (k) => store.get(k) ?? null,
24
+ set: async (k, v) => void store.set(k, v),
25
+ setex: async (k, _ttl, v) => void store.set(k, v),
26
+ del: async (k) => void store.delete(k),
27
+ };
28
+ }
29
+ const RESTRICTED = '2026-08-10T00:00:00Z';
30
+ function row(overrides = {}) {
31
+ return {
32
+ id: '00000000-0000-0000-0000-0000000000aa',
33
+ short_code: 'abc123',
34
+ organization_id: '00000000-0000-0000-0000-0000000000bb',
35
+ original_url: 'https://example.com/landing',
36
+ web_fallback_url: null,
37
+ deep_link_path: null,
38
+ is_active: true,
39
+ warn_at: null,
40
+ owner_suspended_at: RESTRICTED,
41
+ expires_at: null,
42
+ targeting_rules: null,
43
+ template_settings: null,
44
+ org_settings: null,
45
+ utm_parameters: null,
46
+ append_click_id: false,
47
+ ...overrides,
48
+ };
49
+ }
50
+ /**
51
+ * Mock the database so the row's shape follows the SELECT, exactly as Postgres would:
52
+ * `owner_suspended_at` is only present when the query asked for it. That is what makes
53
+ * this a real reproduction rather than a restatement of the fix.
54
+ */
55
+ function mockDb() {
56
+ query.mockReset();
57
+ query.mockImplementation(async (sql) => {
58
+ if (/information_schema\.columns/i.test(sql))
59
+ return { rows: [{ x: 1 }], rowCount: 1 };
60
+ if (/FROM links/i.test(sql)) {
61
+ // The row's shape follows the SELECT, exactly as Postgres would: a column is
62
+ // present only if the query asked for it. That is what makes these real
63
+ // reproductions rather than restatements of the fix.
64
+ const r = row();
65
+ if (!/owner_suspended_at/i.test(sql))
66
+ delete r.owner_suspended_at;
67
+ if (!/template_settings/i.test(sql))
68
+ delete r.template_settings;
69
+ if (!/org_settings/i.test(sql))
70
+ delete r.org_settings;
71
+ return { rows: [r], rowCount: 1 };
72
+ }
73
+ return { rows: [], rowCount: 0 };
74
+ });
75
+ }
76
+ let redirectApp;
77
+ let sdkApp;
78
+ let redis;
79
+ beforeEach(async () => {
80
+ mockDb();
81
+ redis = fakeRedis();
82
+ redirectApp = Fastify();
83
+ redirectApp.decorate('redis', redis);
84
+ await redirectApp.register(redirectRoutes);
85
+ await redirectApp.ready();
86
+ sdkApp = Fastify();
87
+ sdkApp.decorate('redis', redis);
88
+ await sdkApp.register(sdkRoutes);
89
+ await sdkApp.ready();
90
+ });
91
+ afterEach(async () => {
92
+ await new Promise((r) => setImmediate(r));
93
+ await redirectApp.close();
94
+ await sdkApp.close();
95
+ });
96
+ describe('owner restriction cannot be bypassed through the SDK cache', () => {
97
+ it('blocks a restricted owner when the redirect populates the cache itself', async () => {
98
+ const res = await redirectApp.inject({ method: 'GET', url: '/abc123' });
99
+ expect(res.statusCode).toBe(404);
100
+ });
101
+ it('still blocks after an SDK resolve has primed the same cache key', async () => {
102
+ // This is the bypass: prime via the public SDK endpoint, then hit the redirect.
103
+ await sdkApp.inject({ method: 'GET', url: '/api/sdk/v1/resolve/abc123' });
104
+ expect(redis.store.has('link:abc123')).toBe(true);
105
+ const res = await redirectApp.inject({ method: 'GET', url: '/abc123' });
106
+ expect(res.statusCode, 'a restricted owner must stay blocked on a cache hit').toBe(404);
107
+ expect(res.headers.location).toBeUndefined();
108
+ });
109
+ it('the cached row carries owner_suspended_at whichever path wrote it', async () => {
110
+ await sdkApp.inject({ method: 'GET', url: '/api/sdk/v1/resolve/abc123' });
111
+ const cached = JSON.parse(redis.store.get('link:abc123'));
112
+ // Absent (not merely null) is what made the redirect's gate pass.
113
+ expect(Object.prototype.hasOwnProperty.call(cached, 'owner_suspended_at')).toBe(true);
114
+ });
115
+ it('the SDK endpoint itself refuses to resolve a restricted link', async () => {
116
+ // It returns the destination directly, so it must enforce the same policy — that
117
+ // is the information the redirect is refusing to disclose.
118
+ const res = await sdkApp.inject({ method: 'GET', url: '/api/sdk/v1/resolve/abc123' });
119
+ expect(res.statusCode).toBe(404);
120
+ expect(res.body).not.toContain('example.com/landing');
121
+ });
122
+ });
123
+ /**
124
+ * The same cache-shape divergence, one field over.
125
+ *
126
+ * The redirect reads `template_settings` and `org_settings` from this shared key for
127
+ * its URL fallback chain (link, then template, then workspace). While the SDK query
128
+ * omitted them, an SDK resolve left the next redirect unable to see a template-level
129
+ * fallback, so a link relying on one silently fell through to `original_url`.
130
+ */
131
+ describe('the URL fallback chain survives an SDK resolve', () => {
132
+ /** No link-level web fallback; the destination lives on the template. */
133
+ function templateFallbackRow() {
134
+ return {
135
+ ...row({ owner_suspended_at: null }),
136
+ original_url: 'https://example.com/ORIGINAL',
137
+ web_fallback_url: null,
138
+ template_settings: { defaultWebFallbackUrl: 'https://cdn.example.com/template-default' },
139
+ org_settings: null,
140
+ };
141
+ }
142
+ beforeEach(() => {
143
+ query.mockReset();
144
+ query.mockImplementation(async (sql) => {
145
+ if (/information_schema\.columns/i.test(sql))
146
+ return { rows: [{ x: 1 }], rowCount: 1 };
147
+ if (/FROM links/i.test(sql)) {
148
+ const r = templateFallbackRow();
149
+ if (!/owner_suspended_at/i.test(sql))
150
+ delete r.owner_suspended_at;
151
+ if (!/template_settings/i.test(sql))
152
+ delete r.template_settings;
153
+ if (!/org_settings/i.test(sql))
154
+ delete r.org_settings;
155
+ return { rows: [r], rowCount: 1 };
156
+ }
157
+ return { rows: [], rowCount: 0 };
158
+ });
159
+ });
160
+ it('caches template_settings whichever path writes the key', async () => {
161
+ await sdkApp.inject({ method: 'GET', url: '/api/sdk/v1/resolve/abc123' });
162
+ const cached = JSON.parse(redis.store.get('link:abc123'));
163
+ expect(Object.prototype.hasOwnProperty.call(cached, 'template_settings')).toBe(true);
164
+ expect(Object.prototype.hasOwnProperty.call(cached, 'org_settings')).toBe(true);
165
+ });
166
+ });
167
+ //# sourceMappingURL=sdk-cache-bypass.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sdk-cache-bypass.test.js","sourceRoot":"","sources":["../../src/routes/sdk-cache-bypass.test.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"sdk.d.ts","sourceRoot":"","sources":["../../src/routes/sdk.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAe1C;;;GAGG;AACH,wBAAsB,SAAS,CAAC,OAAO,EAAE,eAAe,iBA+nBvD"}
1
+ {"version":3,"file":"sdk.d.ts","sourceRoot":"","sources":["../../src/routes/sdk.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAgB1C;;;GAGG;AACH,wBAAsB,SAAS,CAAC,OAAO,EAAE,eAAe,iBAyrBvD"}