2022-01-18 12:44:08 +08:00
|
|
|
import { User, CreateUser, Users } from '@logto/schemas';
|
2021-07-02 21:14:18 +08:00
|
|
|
import { sql } from 'slonik';
|
2021-08-30 11:30:54 +08:00
|
|
|
|
|
|
|
import { buildInsertInto } from '@/database/insert-into';
|
2021-11-18 11:26:34 +08:00
|
|
|
import { buildUpdateWhere } from '@/database/update-where';
|
2022-02-24 12:29:34 +08:00
|
|
|
import { conditionalSql, convertToIdentifiers, OmitAutoSetFields } from '@/database/utils';
|
2022-04-19 21:49:20 +08:00
|
|
|
import envSet from '@/env-set';
|
2022-03-02 15:44:57 +08:00
|
|
|
import { DeletionError, UpdateError } from '@/errors/SlonikError';
|
2021-07-02 21:14:18 +08:00
|
|
|
|
|
|
|
const { table, fields } = convertToIdentifiers(Users);
|
|
|
|
|
2021-07-26 22:32:18 +08:00
|
|
|
export const findUserByUsername = async (username: string) =>
|
2022-06-02 16:29:17 +08:00
|
|
|
envSet.pool.maybeOne<User>(sql`
|
2021-12-20 14:20:23 +08:00
|
|
|
select ${sql.join(Object.values(fields), sql`,`)}
|
|
|
|
from ${table}
|
|
|
|
where ${fields.username}=${username}
|
|
|
|
`);
|
2021-07-26 22:32:18 +08:00
|
|
|
|
2022-01-31 11:04:55 +08:00
|
|
|
export const findUserByEmail = async (email: string) =>
|
2022-04-19 21:49:20 +08:00
|
|
|
envSet.pool.one<User>(sql`
|
2022-01-31 11:04:55 +08:00
|
|
|
select ${sql.join(Object.values(fields), sql`,`)}
|
|
|
|
from ${table}
|
|
|
|
where ${fields.primaryEmail}=${email}
|
|
|
|
`);
|
|
|
|
|
2022-02-09 16:14:42 +08:00
|
|
|
export const findUserByPhone = async (phone: string) =>
|
2022-04-19 21:49:20 +08:00
|
|
|
envSet.pool.one<User>(sql`
|
2022-02-09 16:14:42 +08:00
|
|
|
select ${sql.join(Object.values(fields), sql`,`)}
|
|
|
|
from ${table}
|
|
|
|
where ${fields.primaryPhone}=${phone}
|
|
|
|
`);
|
|
|
|
|
2021-07-02 21:14:18 +08:00
|
|
|
export const findUserById = async (id: string) =>
|
2022-04-19 21:49:20 +08:00
|
|
|
envSet.pool.one<User>(sql`
|
2021-12-20 14:20:23 +08:00
|
|
|
select ${sql.join(Object.values(fields), sql`,`)}
|
|
|
|
from ${table}
|
|
|
|
where ${fields.id}=${id}
|
|
|
|
`);
|
2021-07-04 17:41:46 +08:00
|
|
|
|
2022-02-11 15:19:18 +08:00
|
|
|
export const findUserByIdentity = async (connectorId: string, userId: string) =>
|
2022-04-19 21:49:20 +08:00
|
|
|
envSet.pool.one<User>(
|
2022-02-11 15:19:18 +08:00
|
|
|
sql`
|
|
|
|
select ${sql.join(Object.values(fields), sql`,`)}
|
|
|
|
from ${table}
|
|
|
|
where ${fields.identities}::json#>>'{${sql.identifier([connectorId])},userId}' = ${userId}
|
|
|
|
`
|
|
|
|
);
|
|
|
|
|
2021-07-04 17:41:46 +08:00
|
|
|
export const hasUser = async (username: string) =>
|
2022-04-19 21:49:20 +08:00
|
|
|
envSet.pool.exists(sql`
|
2021-12-20 14:20:23 +08:00
|
|
|
select ${fields.id}
|
|
|
|
from ${table}
|
|
|
|
where ${fields.username}=${username}
|
|
|
|
`);
|
2021-07-04 17:41:46 +08:00
|
|
|
|
|
|
|
export const hasUserWithId = async (id: string) =>
|
2022-04-19 21:49:20 +08:00
|
|
|
envSet.pool.exists(sql`
|
2021-12-20 14:20:23 +08:00
|
|
|
select ${fields.id}
|
|
|
|
from ${table}
|
|
|
|
where ${fields.id}=${id}
|
|
|
|
`);
|
2021-07-04 17:41:46 +08:00
|
|
|
|
2022-02-07 14:14:42 +08:00
|
|
|
export const hasUserWithEmail = async (email: string) =>
|
2022-04-19 21:49:20 +08:00
|
|
|
envSet.pool.exists(sql`
|
2022-02-07 14:14:42 +08:00
|
|
|
select ${fields.primaryEmail}
|
|
|
|
from ${table}
|
|
|
|
where ${fields.primaryEmail}=${email}
|
|
|
|
`);
|
|
|
|
|
2022-02-09 16:14:42 +08:00
|
|
|
export const hasUserWithPhone = async (phone: string) =>
|
2022-04-19 21:49:20 +08:00
|
|
|
envSet.pool.exists(sql`
|
2022-02-09 16:14:42 +08:00
|
|
|
select ${fields.primaryPhone}
|
|
|
|
from ${table}
|
|
|
|
where ${fields.primaryPhone}=${phone}
|
|
|
|
`);
|
|
|
|
|
2022-02-11 15:19:18 +08:00
|
|
|
export const hasUserWithIdentity = async (connectorId: string, userId: string) =>
|
2022-04-19 21:49:20 +08:00
|
|
|
envSet.pool.exists(
|
2022-02-11 15:19:18 +08:00
|
|
|
sql`
|
|
|
|
select ${fields.id}
|
|
|
|
from ${table}
|
|
|
|
where ${fields.identities}::json#>>'{${sql.identifier([connectorId])},userId}' = ${userId}
|
|
|
|
`
|
|
|
|
);
|
|
|
|
|
2022-04-19 21:49:20 +08:00
|
|
|
export const insertUser = buildInsertInto<CreateUser, User>(Users, {
|
|
|
|
returning: true,
|
|
|
|
});
|
2021-11-18 11:26:34 +08:00
|
|
|
|
2022-02-24 12:29:34 +08:00
|
|
|
const buildUserSearchConditionSql = (search: string) => {
|
|
|
|
const searchFields = [fields.primaryEmail, fields.primaryPhone, fields.username, fields.name];
|
|
|
|
const conditions = searchFields.map((filedName) => sql`${filedName} like ${'%' + search + '%'}`);
|
2022-02-16 15:55:08 +08:00
|
|
|
|
2022-02-24 12:29:34 +08:00
|
|
|
return sql`${sql.join(conditions, sql` or `)}`;
|
|
|
|
};
|
2022-02-16 15:55:08 +08:00
|
|
|
|
2022-02-24 12:29:34 +08:00
|
|
|
export const countUsers = async (search?: string) =>
|
2022-04-19 21:49:20 +08:00
|
|
|
envSet.pool.one<{ count: number }>(sql`
|
2022-02-24 12:29:34 +08:00
|
|
|
select count(*)
|
|
|
|
from ${table}
|
|
|
|
${conditionalSql(search, (search) => sql`where ${buildUserSearchConditionSql(search)}`)}
|
|
|
|
`);
|
|
|
|
|
|
|
|
export const findUsers = async (limit: number, offset: number, search?: string) =>
|
2022-04-19 21:49:20 +08:00
|
|
|
envSet.pool.any<User>(
|
2022-02-24 12:29:34 +08:00
|
|
|
sql`
|
|
|
|
select ${sql.join(Object.values(fields), sql`,`)}
|
|
|
|
from ${table}
|
|
|
|
${conditionalSql(search, (search) => sql`where ${buildUserSearchConditionSql(search)}`)}
|
|
|
|
limit ${limit}
|
|
|
|
offset ${offset}
|
|
|
|
`
|
|
|
|
);
|
2021-11-18 11:26:34 +08:00
|
|
|
|
2022-04-19 21:49:20 +08:00
|
|
|
const updateUser = buildUpdateWhere<CreateUser, User>(Users, true);
|
2021-11-18 11:26:34 +08:00
|
|
|
|
2022-01-18 12:44:08 +08:00
|
|
|
export const updateUserById = async (id: string, set: Partial<OmitAutoSetFields<CreateUser>>) =>
|
2021-11-18 11:26:34 +08:00
|
|
|
updateUser({ set, where: { id } });
|
|
|
|
|
|
|
|
export const deleteUserById = async (id: string) => {
|
2022-04-19 21:49:20 +08:00
|
|
|
const { rowCount } = await envSet.pool.query(sql`
|
2021-12-20 14:20:23 +08:00
|
|
|
delete from ${table}
|
2022-02-28 14:30:27 +08:00
|
|
|
where ${fields.id}=${id}
|
2021-12-20 14:20:23 +08:00
|
|
|
`);
|
2022-01-27 19:26:34 +08:00
|
|
|
|
2021-11-18 11:26:34 +08:00
|
|
|
if (rowCount < 1) {
|
2022-02-14 11:50:47 +08:00
|
|
|
throw new DeletionError(Users.table, id);
|
2021-11-18 11:26:34 +08:00
|
|
|
}
|
|
|
|
};
|
2022-02-17 14:10:26 +08:00
|
|
|
|
|
|
|
export const clearUserCustomDataById = async (id: string) => {
|
2022-04-19 21:49:20 +08:00
|
|
|
const { rowCount } = await envSet.pool.query<User>(sql`
|
2022-02-17 14:10:26 +08:00
|
|
|
update ${table}
|
|
|
|
set ${fields.customData}='{}'::jsonb
|
2022-02-28 14:30:27 +08:00
|
|
|
where ${fields.id}=${id}
|
2022-02-17 14:10:26 +08:00
|
|
|
`);
|
|
|
|
|
|
|
|
if (rowCount < 1) {
|
2022-03-02 15:44:57 +08:00
|
|
|
throw new UpdateError(Users, { set: { customData: {} }, where: { id } });
|
2022-02-17 14:10:26 +08:00
|
|
|
}
|
|
|
|
};
|
2022-03-25 15:48:53 +08:00
|
|
|
|
|
|
|
export const deleteUserIdentity = async (userId: string, connectorId: string) =>
|
2022-04-19 21:49:20 +08:00
|
|
|
envSet.pool.one<User>(sql`
|
2022-03-25 15:48:53 +08:00
|
|
|
update ${table}
|
|
|
|
set ${fields.identities}=${fields.identities}::jsonb-${connectorId}
|
|
|
|
where ${fields.id}=${userId}
|
|
|
|
returning *
|
|
|
|
`);
|
2022-06-09 11:42:52 +08:00
|
|
|
|
|
|
|
export const hasActiveUsers = async () =>
|
|
|
|
envSet.pool.exists(sql`
|
|
|
|
select ${fields.id}
|
|
|
|
from ${table}
|
|
|
|
limit 1
|
|
|
|
`);
|