various improvements (#2671)

* improve oauth config logic

* expire pending login

* move sort to backend
This commit is contained in:
Bernd Storath
2026-06-18 11:14:20 +02:00
committed by GitHub
parent 032347648d
commit e7ea65a898
17 changed files with 144 additions and 147 deletions
@@ -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,