Add signature and authed_requests to database
This commit is contained in:
+1
-1
@@ -17,7 +17,7 @@
|
||||
"scripts": {
|
||||
"analyze": "tsdown --clean --no-fixed-extension --sourcemap source/index.ts && esbuild-analyzer dist/",
|
||||
"build": "tsdown --clean --sourcemap source/index.ts",
|
||||
"dev": "tsx watch source/app.ts",
|
||||
"dev": "tsx watch source/index.ts",
|
||||
"docs": "typedoc --hideGenerator --categorizeByGroup",
|
||||
"format": "prettier --write . && eslint --fix",
|
||||
"spellcheck": "cspell 'source/**' 'test/**' 'playground/**'",
|
||||
|
||||
@@ -32,7 +32,7 @@ const configSchema = z.object({
|
||||
.object({
|
||||
origin: z.string().default('*'),
|
||||
methods: z.array(z.string()).default([ 'GET', 'POST', 'PUT', 'DELETE', 'OPTIONS' ]),
|
||||
allowedHeaders: z.array(z.string()).default([ 'Content-Type', 'cache-control', 'X-Timestamp', 'X-PublicKey', 'X-Signature' ]),
|
||||
allowedHeaders: z.array(z.string()).default([ 'Content-Type', 'cache-control', 'X-Timestamp', 'X-Public-Key', 'X-Signature' ]),
|
||||
})
|
||||
.partial()
|
||||
.prefault({}),
|
||||
@@ -48,6 +48,11 @@ const configSchema = z.object({
|
||||
.int()
|
||||
.positive()
|
||||
.default(5 * 60 * 1000),
|
||||
uniqueRequestCleanupIntervalMs: z.coerce
|
||||
.number()
|
||||
.int()
|
||||
.positive()
|
||||
.default(10 * 60 * 1000),
|
||||
})
|
||||
.prefault({}),
|
||||
});
|
||||
@@ -83,6 +88,7 @@ export class Config {
|
||||
},
|
||||
auth: {
|
||||
timestampWindowMs: process.env.AUTH_TIMESTAMP_WINDOW_MS ? Number(process.env.AUTH_TIMESTAMP_WINDOW_MS) : undefined,
|
||||
uniqueRequestCleanupIntervalMs: process.env.AUTH_UNIQUE_REQUEST_CLEANUP_INTERVAL_MS ? Number(process.env.AUTH_UNIQUE_REQUEST_CLEANUP_INTERVAL_MS) : undefined,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -23,8 +23,19 @@ export const up = async (db: Kysely<DatabaseTables>): Promise<void> => {
|
||||
.addColumn('public_key', 'text', (col) => col.notNull())
|
||||
.addColumn('blob', 'blob', (col) => col.notNull())
|
||||
.addColumn('timestamp', 'integer', (col) => col.notNull().defaultTo(millisecondTime))
|
||||
.addColumn('signature', 'text', (col) => col.notNull())
|
||||
.addPrimaryKeyConstraint('pk_resource_data', [ 'resource_id', 'public_key' ])
|
||||
.execute();
|
||||
|
||||
// Table for authed requests
|
||||
// We will store the signature and the timestamp of the request, and we will clear out rows that are older than our msTimeout for our auth
|
||||
await db.schema
|
||||
.createTable('authed_requests')
|
||||
.ifNotExists()
|
||||
.addColumn('signature', 'text', (col) => col.notNull())
|
||||
.addColumn('timestamp', 'integer', (col) => col.notNull().defaultTo(millisecondTime))
|
||||
.addPrimaryKeyConstraint('pk_authed_requests', [ 'signature' ])
|
||||
.execute();
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -34,5 +45,8 @@ export const up = async (db: Kysely<DatabaseTables>): Promise<void> => {
|
||||
*/
|
||||
export const down = async (db: Kysely<DatabaseTables>): Promise<void> => {
|
||||
await db.schema.dropTable('resource_data').ifExists()
|
||||
.execute();
|
||||
.execute();
|
||||
|
||||
await db.schema.dropTable('authed_requests').ifExists()
|
||||
.execute();
|
||||
};
|
||||
|
||||
@@ -22,9 +22,22 @@ export interface ResourceDataTable {
|
||||
|
||||
/** Millisecond timestamp of the last write. */
|
||||
timestamp: Timestamp;
|
||||
|
||||
/** Signature of the write. */
|
||||
signature: string;
|
||||
}
|
||||
|
||||
export interface AuthedRequestsTable {
|
||||
|
||||
/** Signature of the request. */
|
||||
signature: string;
|
||||
|
||||
/** Millisecond timestamp of the request. */
|
||||
timestamp: Timestamp;
|
||||
}
|
||||
|
||||
/** Complete Kysely schema mapping for the sync server database. */
|
||||
export interface DatabaseTables {
|
||||
resource_data: ResourceDataTable;
|
||||
authed_requests: AuthedRequestsTable;
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ const testConfigDefaultsTo1MiBRequestBodyLimit = (): void => {
|
||||
expect(config.server.host).toBe('0.0.0.0');
|
||||
expect(config.server.cors.origin).toBe('*');
|
||||
expect(config.server.cors.methods).toEqual([ 'GET', 'POST', 'PUT', 'DELETE', 'OPTIONS' ]);
|
||||
expect(config.server.cors.allowedHeaders).toEqual([ 'Content-Type', 'cache-control', 'X-Timestamp', 'X-PublicKey', 'X-Signature' ]);
|
||||
expect(config.server.cors.allowedHeaders).toEqual([ 'Content-Type', 'cache-control', 'X-Timestamp', 'X-Public-Key', 'X-Signature' ]);
|
||||
expect(config.auth.timestampWindowMs).toBe(300000);
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user