@@ -306,6 +306,81 @@ added: v22.13.0
306306This method is used to create SQLite user-defined functions. This method is a
307307wrapper around [ ` sqlite3_create_function_v2() ` ] [ ] .
308308
309+ ### ` database.setAuthorizer(callback) `
310+
311+ <!-- YAML
312+ added: REPLACEME
313+ -->
314+
315+ * ` callback ` {Function|null} The authorizer function to set, or ` null ` to
316+ clear the current authorizer.
317+
318+ Sets an authorizer callback that SQLite will invoke whenever it attempts to
319+ access data or modify the database schema through prepared statements.
320+ This can be used to implement security policies, audit access, or restrict certain operations.
321+ This method is a wrapper around [ ` sqlite3_set_authorizer() ` ] [ ] .
322+
323+ When invoked, the callback receives five arguments:
324+
325+ * ` actionCode ` {number} The type of operation being performed (e.g.,
326+ ` SQLITE_INSERT ` , ` SQLITE_UPDATE ` , ` SQLITE_SELECT ` ).
327+ * ` arg1 ` {string|null} The first argument (context-dependent, often a table name).
328+ * ` arg2 ` {string|null} The second argument (context-dependent, often a column name).
329+ * ` dbName ` {string|null} The name of the database.
330+ * ` triggerOrView ` {string|null} The name of the trigger or view causing the access.
331+
332+ The callback must return one of the following constants:
333+
334+ * ` SQLITE_OK ` - Allow the operation.
335+ * ` SQLITE_DENY ` - Deny the operation (causes an error).
336+ * ` SQLITE_IGNORE ` - Ignore the operation (silently skip).
337+
338+ ``` cjs
339+ const { DatabaseSync , constants } = require (' node:sqlite' );
340+ const db = new DatabaseSync (' :memory:' );
341+
342+ // Set up an authorizer that denies all table creation
343+ db .setAuthorizer ((actionCode ) => {
344+ if (actionCode === constants .SQLITE_CREATE_TABLE ) {
345+ return constants .SQLITE_DENY ;
346+ }
347+ return constants .SQLITE_OK ;
348+ });
349+
350+ // This will work
351+ db .prepare (' SELECT 1' ).get ();
352+
353+ // This will throw an error due to authorization denial
354+ try {
355+ db .exec (' CREATE TABLE blocked (id INTEGER)' );
356+ } catch (err) {
357+ console .log (' Operation blocked:' , err .message );
358+ }
359+ ```
360+
361+ ``` mjs
362+ import { DatabaseSync , constants } from ' node:sqlite' ;
363+ const db = new DatabaseSync (' :memory:' );
364+
365+ // Set up an authorizer that denies all table creation
366+ db .setAuthorizer ((actionCode ) => {
367+ if (actionCode === constants .SQLITE_CREATE_TABLE ) {
368+ return constants .SQLITE_DENY ;
369+ }
370+ return constants .SQLITE_OK ;
371+ });
372+
373+ // This will work
374+ db .prepare (' SELECT 1' ).get ();
375+
376+ // This will throw an error due to authorization denial
377+ try {
378+ db .exec (' CREATE TABLE blocked (id INTEGER)' );
379+ } catch (err) {
380+ console .log (' Operation blocked:' , err .message );
381+ }
382+ ```
383+
309384### ` database.isOpen `
310385
311386<!-- YAML
@@ -833,6 +908,182 @@ resolution handler passed to [`database.applyChangeset()`][]. See also
833908 </tr >
834909</table >
835910
911+ #### Authorization constants
912+
913+ The following constants are used with the [ ` database.setAuthorizer() ` ] [ ] method.
914+
915+ ##### Authorization result codes
916+
917+ One of the following constants must be returned from the authorizer callback
918+ function passed to [ ` database.setAuthorizer() ` ] [ ] .
919+
920+ <table >
921+ <tr >
922+ <th>Constant</th>
923+ <th>Description</th>
924+ </tr >
925+ <tr >
926+ <td><code>SQLITE_OK</code></td>
927+ <td>Allow the operation to proceed normally.</td>
928+ </tr >
929+ <tr >
930+ <td><code>SQLITE_DENY</code></td>
931+ <td>Deny the operation and cause an error to be returned.</td>
932+ </tr >
933+ <tr >
934+ <td><code>SQLITE_IGNORE</code></td>
935+ <td>Ignore the operation and continue as if it had never been requested.</td>
936+ </tr >
937+ </table >
938+
939+ ##### Authorization action codes
940+
941+ The following constants are passed as the first argument to the authorizer
942+ callback function to indicate what type of operation is being authorized.
943+
944+ <table >
945+ <tr >
946+ <th>Constant</th>
947+ <th>Description</th>
948+ </tr >
949+ <tr >
950+ <td><code>SQLITE_CREATE_INDEX</code></td>
951+ <td>Create an index</td>
952+ </tr >
953+ <tr >
954+ <td><code>SQLITE_CREATE_TABLE</code></td>
955+ <td>Create a table</td>
956+ </tr >
957+ <tr >
958+ <td><code>SQLITE_CREATE_TEMP_INDEX</code></td>
959+ <td>Create a temporary index</td>
960+ </tr >
961+ <tr >
962+ <td><code>SQLITE_CREATE_TEMP_TABLE</code></td>
963+ <td>Create a temporary table</td>
964+ </tr >
965+ <tr >
966+ <td><code>SQLITE_CREATE_TEMP_TRIGGER</code></td>
967+ <td>Create a temporary trigger</td>
968+ </tr >
969+ <tr >
970+ <td><code>SQLITE_CREATE_TEMP_VIEW</code></td>
971+ <td>Create a temporary view</td>
972+ </tr >
973+ <tr >
974+ <td><code>SQLITE_CREATE_TRIGGER</code></td>
975+ <td>Create a trigger</td>
976+ </tr >
977+ <tr >
978+ <td><code>SQLITE_CREATE_VIEW</code></td>
979+ <td>Create a view</td>
980+ </tr >
981+ <tr >
982+ <td><code>SQLITE_DELETE</code></td>
983+ <td>Delete from a table</td>
984+ </tr >
985+ <tr >
986+ <td><code>SQLITE_DROP_INDEX</code></td>
987+ <td>Drop an index</td>
988+ </tr >
989+ <tr >
990+ <td><code>SQLITE_DROP_TABLE</code></td>
991+ <td>Drop a table</td>
992+ </tr >
993+ <tr >
994+ <td><code>SQLITE_DROP_TEMP_INDEX</code></td>
995+ <td>Drop a temporary index</td>
996+ </tr >
997+ <tr >
998+ <td><code>SQLITE_DROP_TEMP_TABLE</code></td>
999+ <td>Drop a temporary table</td>
1000+ </tr >
1001+ <tr >
1002+ <td><code>SQLITE_DROP_TEMP_TRIGGER</code></td>
1003+ <td>Drop a temporary trigger</td>
1004+ </tr >
1005+ <tr >
1006+ <td><code>SQLITE_DROP_TEMP_VIEW</code></td>
1007+ <td>Drop a temporary view</td>
1008+ </tr >
1009+ <tr >
1010+ <td><code>SQLITE_DROP_TRIGGER</code></td>
1011+ <td>Drop a trigger</td>
1012+ </tr >
1013+ <tr >
1014+ <td><code>SQLITE_DROP_VIEW</code></td>
1015+ <td>Drop a view</td>
1016+ </tr >
1017+ <tr >
1018+ <td><code>SQLITE_INSERT</code></td>
1019+ <td>Insert into a table</td>
1020+ </tr >
1021+ <tr >
1022+ <td><code>SQLITE_PRAGMA</code></td>
1023+ <td>Execute a PRAGMA statement</td>
1024+ </tr >
1025+ <tr >
1026+ <td><code>SQLITE_READ</code></td>
1027+ <td>Read from a table</td>
1028+ </tr >
1029+ <tr >
1030+ <td><code>SQLITE_SELECT</code></td>
1031+ <td>Execute a SELECT statement</td>
1032+ </tr >
1033+ <tr >
1034+ <td><code>SQLITE_TRANSACTION</code></td>
1035+ <td>Begin, commit, or rollback a transaction</td>
1036+ </tr >
1037+ <tr >
1038+ <td><code>SQLITE_UPDATE</code></td>
1039+ <td>Update a table</td>
1040+ </tr >
1041+ <tr >
1042+ <td><code>SQLITE_ATTACH</code></td>
1043+ <td>Attach a database</td>
1044+ </tr >
1045+ <tr >
1046+ <td><code>SQLITE_DETACH</code></td>
1047+ <td>Detach a database</td>
1048+ </tr >
1049+ <tr >
1050+ <td><code>SQLITE_ALTER_TABLE</code></td>
1051+ <td>Alter a table</td>
1052+ </tr >
1053+ <tr >
1054+ <td><code>SQLITE_REINDEX</code></td>
1055+ <td>Reindex</td>
1056+ </tr >
1057+ <tr >
1058+ <td><code>SQLITE_ANALYZE</code></td>
1059+ <td>Analyze the database</td>
1060+ </tr >
1061+ <tr >
1062+ <td><code>SQLITE_CREATE_VTABLE</code></td>
1063+ <td>Create a virtual table</td>
1064+ </tr >
1065+ <tr >
1066+ <td><code>SQLITE_DROP_VTABLE</code></td>
1067+ <td>Drop a virtual table</td>
1068+ </tr >
1069+ <tr >
1070+ <td><code>SQLITE_FUNCTION</code></td>
1071+ <td>Use a function</td>
1072+ </tr >
1073+ <tr >
1074+ <td><code>SQLITE_SAVEPOINT</code></td>
1075+ <td>Create, release, or rollback a savepoint</td>
1076+ </tr >
1077+ <tr >
1078+ <td><code>SQLITE_COPY</code></td>
1079+ <td>Copy data (legacy)</td>
1080+ </tr >
1081+ <tr >
1082+ <td><code>SQLITE_RECURSIVE</code></td>
1083+ <td>Recursive query</td>
1084+ </tr >
1085+ </table >
1086+
8361087[ Changesets and Patchsets ] : https://www.sqlite.org/sessionintro.html#changesets_and_patchsets
8371088[ Constants Passed To The Conflict Handler ] : https://www.sqlite.org/session/c_changeset_conflict.html
8381089[ Constants Returned From The Conflict Handler ] : https://www.sqlite.org/session/c_changeset_abort.html
@@ -844,6 +1095,7 @@ resolution handler passed to [`database.applyChangeset()`][]. See also
8441095[ `SQLITE_DIRECTONLY` ] : https://www.sqlite.org/c3ref/c_deterministic.html
8451096[ `SQLITE_MAX_FUNCTION_ARG` ] : https://www.sqlite.org/limits.html#max_function_arg
8461097[ `database.applyChangeset()` ] : #databaseapplychangesetchangeset-options
1098+ [ `database.setAuthorizer()` ] : #databasesetauthorizercallback
8471099[ `sqlite3_backup_finish()` ] : https://www.sqlite.org/c3ref/backup_finish.html#sqlite3backupfinish
8481100[ `sqlite3_backup_init()` ] : https://www.sqlite.org/c3ref/backup_finish.html#sqlite3backupinit
8491101[ `sqlite3_backup_step()` ] : https://www.sqlite.org/c3ref/backup_finish.html#sqlite3backupstep
@@ -863,6 +1115,7 @@ resolution handler passed to [`database.applyChangeset()`][]. See also
8631115[ `sqlite3_last_insert_rowid()` ] : https://www.sqlite.org/c3ref/last_insert_rowid.html
8641116[ `sqlite3_load_extension()` ] : https://www.sqlite.org/c3ref/load_extension.html
8651117[ `sqlite3_prepare_v2()` ] : https://www.sqlite.org/c3ref/prepare.html
1118+ [ `sqlite3_set_authorizer()` ] : https://sqlite.org/c3ref/set_authorizer.html
8661119[ `sqlite3_sql()` ] : https://www.sqlite.org/c3ref/expanded_sql.html
8671120[ `sqlite3changeset_apply()` ] : https://www.sqlite.org/session/sqlite3changeset_apply.html
8681121[ `sqlite3session_attach()` ] : https://www.sqlite.org/session/sqlite3session_attach.html
0 commit comments