|
|
|
@ -4,6 +4,7 @@ import { client } from './schema'; |
|
|
|
import type { |
|
|
|
ClientCreateFromExistingType, |
|
|
|
ClientCreateType, |
|
|
|
ClientQueryType, |
|
|
|
UpdateClientType, |
|
|
|
} from './types'; |
|
|
|
import type { DBType } from '#db/sqlite'; |
|
|
|
@ -18,63 +19,9 @@ function createPreparedStatement(db: DBType) { |
|
|
|
}, |
|
|
|
}) |
|
|
|
.prepare(), |
|
|
|
findAllPublic: db.query.client |
|
|
|
.findMany({ |
|
|
|
with: { |
|
|
|
oneTimeLink: true, |
|
|
|
}, |
|
|
|
columns: { |
|
|
|
privateKey: false, |
|
|
|
preSharedKey: false, |
|
|
|
}, |
|
|
|
}) |
|
|
|
.prepare(), |
|
|
|
findById: db.query.client |
|
|
|
.findFirst({ where: eq(client.id, sql.placeholder('id')) }) |
|
|
|
.prepare(), |
|
|
|
findByUserId: db.query.client |
|
|
|
.findMany({ |
|
|
|
where: eq(client.userId, sql.placeholder('userId')), |
|
|
|
with: { oneTimeLink: true }, |
|
|
|
columns: { |
|
|
|
privateKey: false, |
|
|
|
preSharedKey: false, |
|
|
|
}, |
|
|
|
}) |
|
|
|
.prepare(), |
|
|
|
findAllPublicFiltered: db.query.client |
|
|
|
.findMany({ |
|
|
|
where: or( |
|
|
|
like(client.name, sql.placeholder('filter')), |
|
|
|
like(client.ipv4Address, sql.placeholder('filter')), |
|
|
|
like(client.ipv6Address, sql.placeholder('filter')) |
|
|
|
), |
|
|
|
with: { |
|
|
|
oneTimeLink: true, |
|
|
|
}, |
|
|
|
columns: { |
|
|
|
privateKey: false, |
|
|
|
preSharedKey: false, |
|
|
|
}, |
|
|
|
}) |
|
|
|
.prepare(), |
|
|
|
findByUserIdFiltered: db.query.client |
|
|
|
.findMany({ |
|
|
|
where: and( |
|
|
|
eq(client.userId, sql.placeholder('userId')), |
|
|
|
or( |
|
|
|
like(client.name, sql.placeholder('filter')), |
|
|
|
like(client.ipv4Address, sql.placeholder('filter')), |
|
|
|
like(client.ipv6Address, sql.placeholder('filter')) |
|
|
|
) |
|
|
|
), |
|
|
|
with: { oneTimeLink: true }, |
|
|
|
columns: { |
|
|
|
privateKey: false, |
|
|
|
preSharedKey: false, |
|
|
|
}, |
|
|
|
}) |
|
|
|
.prepare(), |
|
|
|
toggle: db |
|
|
|
.update(client) |
|
|
|
.set({ enabled: sql.placeholder('enabled') as never as boolean }) |
|
|
|
@ -96,15 +43,6 @@ export class ClientService { |
|
|
|
this.#statements = createPreparedStatement(db); |
|
|
|
} |
|
|
|
|
|
|
|
async getForUser(userId: ID) { |
|
|
|
const result = await this.#statements.findByUserId.execute({ userId }); |
|
|
|
return result.map((row) => ({ |
|
|
|
...row, |
|
|
|
createdAt: new Date(row.createdAt), |
|
|
|
updatedAt: new Date(row.updatedAt), |
|
|
|
})); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* Never return values directly from this function. Use {@link getAllPublic} instead. |
|
|
|
*/ |
|
|
|
@ -120,25 +58,40 @@ export class ClientService { |
|
|
|
/** |
|
|
|
* Returns all clients without sensitive data |
|
|
|
*/ |
|
|
|
async getAllPublic() { |
|
|
|
const result = await this.#statements.findAllPublic.execute(); |
|
|
|
return result.map((row) => ({ |
|
|
|
...row, |
|
|
|
createdAt: new Date(row.createdAt), |
|
|
|
updatedAt: new Date(row.updatedAt), |
|
|
|
})); |
|
|
|
} |
|
|
|
async getAllPublic({ filter, sort }: ClientQueryType) { |
|
|
|
const filters = []; |
|
|
|
|
|
|
|
/** |
|
|
|
* Get clients based on user ID and filter conditions |
|
|
|
*/ |
|
|
|
async getForUserFiltered(userId: ID, filter: string) { |
|
|
|
const filterPattern = `%${filter.toLowerCase()}%`; |
|
|
|
if (filter?.trim()) { |
|
|
|
const filterPattern = `%${filter?.toLowerCase()}%`; |
|
|
|
filters.push( |
|
|
|
or( |
|
|
|
like(client.name, filterPattern), |
|
|
|
like(client.ipv4Address, filterPattern), |
|
|
|
like(client.ipv6Address, filterPattern) |
|
|
|
) |
|
|
|
); |
|
|
|
} |
|
|
|
|
|
|
|
const result = await this.#statements.findByUserIdFiltered.execute({ |
|
|
|
userId, |
|
|
|
filter: filterPattern, |
|
|
|
}); |
|
|
|
const result = await this.#db.query.client |
|
|
|
.findMany({ |
|
|
|
with: { |
|
|
|
oneTimeLink: true, |
|
|
|
}, |
|
|
|
where: and(...filters), |
|
|
|
columns: { |
|
|
|
privateKey: false, |
|
|
|
preSharedKey: false, |
|
|
|
}, |
|
|
|
orderBy: (t, { asc, desc }) => { |
|
|
|
if (sort === 'desc') { |
|
|
|
return desc(t.name); |
|
|
|
} else { |
|
|
|
// default to asc
|
|
|
|
return asc(t.name); |
|
|
|
} |
|
|
|
}, |
|
|
|
}) |
|
|
|
.execute(); |
|
|
|
|
|
|
|
return result.map((row) => ({ |
|
|
|
...row, |
|
|
|
@ -148,14 +101,40 @@ export class ClientService { |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* Get all clients based on filter conditions without sensitive data |
|
|
|
* Returns all clients without sensitive data belonging to user |
|
|
|
*/ |
|
|
|
async getAllPublicFiltered(filter: string) { |
|
|
|
const filterPattern = `%${filter.toLowerCase()}%`; |
|
|
|
async getAllForUser(userId: ID, { filter, sort }: ClientQueryType) { |
|
|
|
const filters = []; |
|
|
|
|
|
|
|
const result = await this.#statements.findAllPublicFiltered.execute({ |
|
|
|
filter: filterPattern, |
|
|
|
}); |
|
|
|
if (filter?.trim()) { |
|
|
|
const filterPattern = `%${filter?.toLowerCase()}%`; |
|
|
|
filters.push( |
|
|
|
or( |
|
|
|
like(client.name, filterPattern), |
|
|
|
like(client.ipv4Address, filterPattern), |
|
|
|
like(client.ipv6Address, filterPattern) |
|
|
|
) |
|
|
|
); |
|
|
|
} |
|
|
|
|
|
|
|
const result = await this.#db.query.client |
|
|
|
.findMany({ |
|
|
|
where: and(eq(client.userId, userId), ...filters), |
|
|
|
with: { oneTimeLink: true }, |
|
|
|
columns: { |
|
|
|
privateKey: false, |
|
|
|
preSharedKey: false, |
|
|
|
}, |
|
|
|
orderBy: (t, { asc, desc }) => { |
|
|
|
if (sort === 'desc') { |
|
|
|
return desc(t.name); |
|
|
|
} else { |
|
|
|
// default to asc
|
|
|
|
return asc(t.name); |
|
|
|
} |
|
|
|
}, |
|
|
|
}) |
|
|
|
.execute(); |
|
|
|
|
|
|
|
return result.map((row) => ({ |
|
|
|
...row, |
|
|
|
|