json-rest-api 1.0.10 → 1.0.11
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/.claude/settings.local.json +9 -1
- package/AGENTS.md +34 -0
- package/CLAUDE.md +26 -1
- package/CRUSH.md +55 -0
- package/README.md +3 -3
- package/TODO.todo +8 -0
- package/docs/API.md +17 -18
- package/docs/COMPARISON.md +18 -13
- package/docs/GUIDE/GUIDE_1_Initial_Setup.md +17 -21
- package/docs/GUIDE/GUIDE_2_1_The_Starting_Point.md +33 -2
- package/docs/GUIDE/GUIDE_2_2_Manipulating_And_Searching_Tables.md +61 -7
- package/docs/GUIDE/GUIDE_2_3_BelongsTo_Relationships.md +58 -61
- package/docs/GUIDE/GUIDE_2_4_HasMany_Records.md +37 -37
- package/docs/GUIDE/GUIDE_2_5_HasMany_Polymorphic.md +103 -87
- package/docs/GUIDE/GUIDE_2_6_Many_To_Many.md +37 -34
- package/docs/GUIDE/GUIDE_2_7_Pagination_And_Ordering.md +45 -42
- package/docs/GUIDE/GUIDE_2_8_Effects_of_PUT_and_PATCH.md +3 -3
- package/docs/GUIDE/GUIDE_2_Data_And_Relations.md +1 -1
- package/docs/GUIDE/GUIDE_3_Field_Transformations.md +5 -5
- package/docs/GUIDE/GUIDE_4_Authentication_And_Permissions.md +498 -755
- package/docs/GUIDE/GUIDE_6_Positioning.md +1 -3
- package/docs/GUIDE/GUIDE_7_Hooks_Data_Management_And_Plugins.md +4 -5
- package/docs/GUIDE/GUIDE_X_Bulk_Operations.md +15 -6
- package/docs/GUIDE/GUIDE_X_Cors.md +2 -5
- package/docs/GUIDE/GUIDE_X_File_Uploads.md +2 -3
- package/docs/GUIDE/GUIDE_X_Multihome.md +1 -4
- package/docs/GUIDE/GUIDE_X_SocketIO.md +0 -2
- package/docs/GUIDE/GUIDE_X_URL_Management.md +317 -0
- package/docs/GUIDE/index.md +3 -0
- package/docs/QUICKSTART.md +12 -12
- package/docs/index.md +2 -2
- package/docs/mini-guides/file-uploads-complete.md +0 -1
- package/examples/url-override-example.js +137 -0
- package/index.js +7 -1
- package/package.json +5 -9
- package/plugins/core/bulk-operations-plugin.js +2 -0
- package/plugins/core/connectors/express-plugin.js +43 -24
- package/plugins/core/connectors/lib/request-helpers.js +2 -2
- package/plugins/core/lib/anyapi/anyapi-registry.js +821 -0
- package/plugins/core/lib/anyapi/query/anyapi-query-adapter.js +647 -0
- package/plugins/core/lib/anyapi/schema-utils.js +186 -0
- package/plugins/core/lib/anyapi/utils/descriptor-helpers.js +113 -0
- package/plugins/core/lib/dbTablesOperations.js +305 -0
- package/plugins/core/lib/querying/knex-cross-table-search.js +64 -108
- package/plugins/core/lib/querying/knex-json-api-transformers-querying.js +21 -27
- package/plugins/core/lib/querying/knex-pagination-helpers.js +36 -20
- package/plugins/core/lib/querying/knex-query-helpers-base.js +49 -14
- package/plugins/core/lib/querying/knex-query-helpers.js +378 -222
- package/plugins/core/lib/querying/knex-relationship-includes.js +262 -87
- package/plugins/core/lib/querying/url-helpers.js +119 -0
- package/plugins/core/lib/querying-writing/compile-schemas.js +36 -28
- package/plugins/core/lib/querying-writing/database-capabilities.js +10 -9
- package/plugins/core/lib/querying-writing/knex-field-helpers.js +9 -3
- package/plugins/core/lib/querying-writing/knex-json-api-transformers.js +2 -2
- package/plugins/core/lib/querying-writing/payload-validators.js +10 -16
- package/plugins/core/lib/querying-writing/schema-helpers.js +52 -60
- package/plugins/core/lib/querying-writing/scope-validations.js +78 -22
- package/plugins/core/lib/querying-writing/simplified-helpers.js +208 -61
- package/plugins/core/lib/storage/storage-adapter.js +160 -0
- package/plugins/core/lib/writing/relationship-processor.js +4 -11
- package/plugins/core/rest-api-access.js +456 -0
- package/plugins/core/rest-api-anyapi-knex-plugin.js +2285 -0
- package/plugins/core/rest-api-knex-plugin.js +226 -87
- package/plugins/core/rest-api-multihome-plugin.js +89 -27
- package/plugins/core/rest-api-plugin-hooks/turn-scope-init-into-vars.js +0 -1
- package/plugins/core/rest-api-plugin-methods/check-permissions.js +1 -5
- package/plugins/core/rest-api-plugin-methods/common.js +46 -10
- package/plugins/core/rest-api-plugin-methods/delete-relationship.js +31 -27
- package/plugins/core/rest-api-plugin-methods/delete.js +1 -4
- package/plugins/core/rest-api-plugin-methods/enrich-attributes.js +13 -1
- package/plugins/core/rest-api-plugin-methods/get-related.js +114 -56
- package/plugins/core/rest-api-plugin-methods/get-relationship.js +4 -3
- package/plugins/core/rest-api-plugin-methods/get.js +2 -5
- package/plugins/core/rest-api-plugin-methods/patch.js +15 -16
- package/plugins/core/rest-api-plugin-methods/post-relationship.js +21 -14
- package/plugins/core/rest-api-plugin-methods/post.js +23 -11
- package/plugins/core/rest-api-plugin-methods/put.js +18 -21
- package/plugins/core/rest-api-plugin-methods/query.js +3 -4
- package/plugins/core/rest-api-plugin-methods/release.js +13 -0
- package/plugins/core/rest-api-plugin.js +3 -4
- package/plugins/core/rest-api-positioning-plugin.js +253 -76
- package/plugins/core/socketio-plugin.js +436 -502
- package/quickTest.js +2 -2
- package/scripts/debug-anyapi-review-filter.mjs +63 -0
- package/scripts/inspect-anyapi-descriptor-country.mjs +19 -0
- package/scripts/inspect-anyapi-descriptor.mjs +19 -0
- package/test-debug.js +59 -0
- package/tests/README.md +7 -1
- package/tests/anyapi-basic.test.js +102 -0
- package/tests/anyapi-cursor-pagination.test.js +144 -0
- package/tests/computed-fields.test.js +27 -12
- package/tests/cors.test.js +5 -6
- package/tests/curl.test.js +1 -1
- package/tests/custom-idproperty-relationships.test.js +37 -29
- package/tests/field-getters.test.js +25 -7
- package/tests/fixtures/api-configs.js +576 -150
- package/tests/helpers/storage-mode.js +65 -0
- package/tests/helpers/test-utils.js +85 -3
- package/tests/include-depth-validation.test.js +35 -1
- package/tests/nested-includes.test.js +130 -103
- package/tests/pagination-cursor-multifield.test.js +17 -13
- package/tests/pagination-enhanced.test.js +19 -24
- package/tests/polymorphic-simple.test.js +9 -9
- package/tests/positioning-advanced.test.js +19 -19
- package/tests/positioning-extended.test.js +25 -25
- package/tests/positioning-multifilter.test.js +62 -62
- package/tests/positioning.test.js +7 -7
- package/tests/queries.test.js +5 -5
- package/tests/query-limits.test.js +77 -92
- package/tests/rest-api-access.test.js +206 -0
- package/tests/searchschema-merge.test.js +182 -0
- package/tests/socketio.test.js +33 -14
- package/tests/virtual-fields.test.js +0 -1
- package/docs/DOCS_ALL.md +0 -21894
- package/plugins/core/jwt-auth-plugin.js +0 -897
- package/plugins/core/lib/jwt-auth-helpers.js +0 -130
- package/tests/jwt-auth.test.js +0 -692
|
@@ -1,130 +0,0 @@
|
|
|
1
|
-
import { requirePackage } from 'hooked-api';
|
|
2
|
-
|
|
3
|
-
let jwt;
|
|
4
|
-
try {
|
|
5
|
-
jwt = (await import('jsonwebtoken')).default;
|
|
6
|
-
} catch (e) {
|
|
7
|
-
requirePackage('jsonwebtoken', 'jwt-auth',
|
|
8
|
-
'JSON Web Token support is required for JWT authentication. This is a peer dependency.');
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Verify JWT token with multiple strategies
|
|
13
|
-
*/
|
|
14
|
-
export async function verifyToken(token, options) {
|
|
15
|
-
const { secret, publicKey, algorithms, audience, issuer, jwksClient } = options;
|
|
16
|
-
|
|
17
|
-
// Decode token to get header
|
|
18
|
-
const decoded = jwt.decode(token, { complete: true });
|
|
19
|
-
if (!decoded) {
|
|
20
|
-
throw new Error('Invalid token format');
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
let verifyOptions = {
|
|
24
|
-
algorithms,
|
|
25
|
-
audience,
|
|
26
|
-
issuer
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
// Get the signing key
|
|
30
|
-
let signingKey;
|
|
31
|
-
|
|
32
|
-
if (jwksClient && decoded.header.kid) {
|
|
33
|
-
// Use JWKS
|
|
34
|
-
const key = await jwksClient.getSigningKey(decoded.header.kid);
|
|
35
|
-
signingKey = key.getPublicKey();
|
|
36
|
-
} else if (publicKey) {
|
|
37
|
-
// Use public key
|
|
38
|
-
signingKey = publicKey;
|
|
39
|
-
} else if (secret) {
|
|
40
|
-
// Use secret
|
|
41
|
-
signingKey = secret;
|
|
42
|
-
} else {
|
|
43
|
-
throw new Error('No signing key available');
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// Verify token
|
|
47
|
-
return jwt.verify(token, signingKey, verifyOptions);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Create the revoked tokens resource
|
|
52
|
-
*/
|
|
53
|
-
export async function createRevocationResource(api, tableName) {
|
|
54
|
-
// Check if resource already exists
|
|
55
|
-
if (api.resources[tableName]) {
|
|
56
|
-
return;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
await api.addResource(tableName, {
|
|
60
|
-
schema: {
|
|
61
|
-
id: { type: 'id' },
|
|
62
|
-
jti: { type: 'string', required: true, unique: true },
|
|
63
|
-
user_id: { type: 'string', required: true },
|
|
64
|
-
expires_at: { type: 'dateTime', required: true },
|
|
65
|
-
revoked_at: { type: 'dateTime', required: true }
|
|
66
|
-
},
|
|
67
|
-
|
|
68
|
-
// Add index for cleanup queries
|
|
69
|
-
indexes: [
|
|
70
|
-
{ fields: ['expires_at'] },
|
|
71
|
-
{ fields: ['user_id'] }
|
|
72
|
-
],
|
|
73
|
-
|
|
74
|
-
// Hide from API discovery
|
|
75
|
-
hidden: true
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
// Create table if using Knex
|
|
79
|
-
if (api.resources[tableName].createKnexTable) {
|
|
80
|
-
await api.resources[tableName].createKnexTable();
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* Check if token is revoked
|
|
86
|
-
*/
|
|
87
|
-
export async function checkRevocation(jti, api, config, memoryStore) {
|
|
88
|
-
if (config.storage === 'database') {
|
|
89
|
-
try {
|
|
90
|
-
const result = await api.resources[config.tableName].get({
|
|
91
|
-
id: jti,
|
|
92
|
-
simplified: true
|
|
93
|
-
});
|
|
94
|
-
return !!result;
|
|
95
|
-
} catch (error) {
|
|
96
|
-
// Not found = not revoked
|
|
97
|
-
if (error.subtype === 'not_found') {
|
|
98
|
-
return false;
|
|
99
|
-
}
|
|
100
|
-
throw error;
|
|
101
|
-
}
|
|
102
|
-
} else {
|
|
103
|
-
// Memory storage - also clean up expired tokens while we're here
|
|
104
|
-
const now = Date.now();
|
|
105
|
-
for (const [storedJti, data] of memoryStore.entries()) {
|
|
106
|
-
if (data.expiresAt < now) {
|
|
107
|
-
memoryStore.delete(storedJti);
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
return memoryStore.has(jti);
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
/**
|
|
116
|
-
* Clean up expired tokens from revocation table
|
|
117
|
-
*/
|
|
118
|
-
export async function cleanupExpiredTokens(api, tableName) {
|
|
119
|
-
const knex = api.knex || api.vars?.knex;
|
|
120
|
-
|
|
121
|
-
if (!knex) {
|
|
122
|
-
throw new Error('Knex instance not found for cleanup');
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
const result = await knex(tableName)
|
|
126
|
-
.where('expires_at', '<', new Date())
|
|
127
|
-
.delete();
|
|
128
|
-
|
|
129
|
-
return result;
|
|
130
|
-
}
|