From e7458f8a2b4fff37e1b281183cdedfd774934987 Mon Sep 17 00:00:00 2001 From: Wang Sijie Date: Wed, 9 Feb 2022 12:55:06 +0800 Subject: [PATCH] feat(schema): user identities (#215) --- packages/core/src/database/find-many.test.ts | 12 ++++++------ packages/schemas/src/db-entries/user.ts | 14 +++++++++++++- packages/schemas/src/foundations/jsonb-types.ts | 9 +++++++++ packages/schemas/tables/users.sql | 1 + 4 files changed, 29 insertions(+), 7 deletions(-) diff --git a/packages/core/src/database/find-many.test.ts b/packages/core/src/database/find-many.test.ts index e2b1c76b9..b5ff16595 100644 --- a/packages/core/src/database/find-many.test.ts +++ b/packages/core/src/database/find-many.test.ts @@ -7,7 +7,7 @@ import { buildFindMany } from './find-many'; describe('buildFindMany()', () => { it('matches expected sql', async () => { const pool = createTestPool( - 'select "id", "username", "primary_email", "primary_phone", "password_encrypted", "password_encryption_method", "password_encryption_salt", "role_names"\nfrom "users"' + 'select "id", "username", "primary_email", "primary_phone", "password_encrypted", "password_encryption_method", "password_encryption_salt", "role_names", "identities"\nfrom "users"' ); const findMany = buildFindMany(pool, Users); await findMany(); @@ -15,7 +15,7 @@ describe('buildFindMany()', () => { it('matches expected sql with where conditions', async () => { const pool = createTestPool( - 'select "id", "username", "primary_email", "primary_phone", "password_encrypted", "password_encryption_method", "password_encryption_salt", "role_names"\nfrom "users"\nwhere "id"=$1' + 'select "id", "username", "primary_email", "primary_phone", "password_encrypted", "password_encryption_method", "password_encryption_salt", "role_names", "identities"\nfrom "users"\nwhere "id"=$1' ); const findMany = buildFindMany(pool, Users); await findMany({ where: { id: '123' } }); @@ -23,7 +23,7 @@ describe('buildFindMany()', () => { it('matches expected sql with limit', async () => { const pool = createTestPool( - 'select "id", "username", "primary_email", "primary_phone", "password_encrypted", "password_encryption_method", "password_encryption_salt", "role_names"\nfrom "users"\nlimit $1' + 'select "id", "username", "primary_email", "primary_phone", "password_encrypted", "password_encryption_method", "password_encryption_salt", "role_names", "identities"\nfrom "users"\nlimit $1' ); const findMany = buildFindMany(pool, Users); await findMany({ limit: 10 }); @@ -31,7 +31,7 @@ describe('buildFindMany()', () => { it('matches expected sql with offset', async () => { const pool = createTestPool( - 'select "id", "username", "primary_email", "primary_phone", "password_encrypted", "password_encryption_method", "password_encryption_salt", "role_names"\nfrom "users"\noffset $1' + 'select "id", "username", "primary_email", "primary_phone", "password_encrypted", "password_encryption_method", "password_encryption_salt", "role_names", "identities"\nfrom "users"\noffset $1' ); const findMany = buildFindMany(pool, Users); await findMany({ offset: 10 }); @@ -39,7 +39,7 @@ describe('buildFindMany()', () => { it('matches expected sql with offset 0', async () => { const pool = createTestPool( - 'select "id", "username", "primary_email", "primary_phone", "password_encrypted", "password_encryption_method", "password_encryption_salt", "role_names"\nfrom "users"' + 'select "id", "username", "primary_email", "primary_phone", "password_encrypted", "password_encryption_method", "password_encryption_salt", "role_names", "identities"\nfrom "users"' ); const findMany = buildFindMany(pool, Users); await findMany({ offset: 0 }); @@ -47,7 +47,7 @@ describe('buildFindMany()', () => { it('matches expected sql with where conditions, limit and offset', async () => { const pool = createTestPool( - 'select "id", "username", "primary_email", "primary_phone", "password_encrypted", "password_encryption_method", "password_encryption_salt", "role_names"\nfrom "users"\nwhere "id"=$1\nlimit $2\noffset $3' + 'select "id", "username", "primary_email", "primary_phone", "password_encrypted", "password_encryption_method", "password_encryption_salt", "role_names", "identities"\nfrom "users"\nwhere "id"=$1\nlimit $2\noffset $3' ); const findMany = buildFindMany(pool, Users); await findMany({ where: { id: '123' }, limit: 20, offset: 20 }); diff --git a/packages/schemas/src/db-entries/user.ts b/packages/schemas/src/db-entries/user.ts index f3903cf74..bbd48ef7f 100644 --- a/packages/schemas/src/db-entries/user.ts +++ b/packages/schemas/src/db-entries/user.ts @@ -2,7 +2,14 @@ import { z } from 'zod'; -import { RoleNames, roleNamesGuard, GeneratedSchema, Guard } from '../foundations'; +import { + RoleNames, + roleNamesGuard, + Identities, + identitiesGuard, + GeneratedSchema, + Guard, +} from '../foundations'; import { PasswordEncryptionMethod } from './custom-types'; export type CreateUser = { @@ -14,6 +21,7 @@ export type CreateUser = { passwordEncryptionMethod?: PasswordEncryptionMethod | null; passwordEncryptionSalt?: string | null; roleNames?: RoleNames; + identities?: Identities; }; export type User = { @@ -25,6 +33,7 @@ export type User = { passwordEncryptionMethod: PasswordEncryptionMethod | null; passwordEncryptionSalt: string | null; roleNames: RoleNames; + identities: Identities; }; const createGuard: Guard = z.object({ @@ -36,6 +45,7 @@ const createGuard: Guard = z.object({ passwordEncryptionMethod: z.nativeEnum(PasswordEncryptionMethod).nullable().optional(), passwordEncryptionSalt: z.string().nullable().optional(), roleNames: roleNamesGuard.optional(), + identities: identitiesGuard.optional(), }); export const Users: GeneratedSchema = Object.freeze({ @@ -50,6 +60,7 @@ export const Users: GeneratedSchema = Object.freeze({ passwordEncryptionMethod: 'password_encryption_method', passwordEncryptionSalt: 'password_encryption_salt', roleNames: 'role_names', + identities: 'identities', }, fieldKeys: [ 'id', @@ -60,6 +71,7 @@ export const Users: GeneratedSchema = Object.freeze({ 'passwordEncryptionMethod', 'passwordEncryptionSalt', 'roleNames', + 'identities', ], createGuard, }); diff --git a/packages/schemas/src/foundations/jsonb-types.ts b/packages/schemas/src/foundations/jsonb-types.ts index b0f4316cf..cdc79aace 100644 --- a/packages/schemas/src/foundations/jsonb-types.ts +++ b/packages/schemas/src/foundations/jsonb-types.ts @@ -45,6 +45,15 @@ export const roleNamesGuard = z.string().array(); export type RoleNames = z.infer; +const identityGuard = z.object({ + userId: z.string(), + details: z.object({}).optional(), // Connector's userinfo details, schemaless +}); +export const identitiesGuard = z.record(identityGuard); + +export type Identity = z.infer; +export type Identities = z.infer; + /** * User Logs */ diff --git a/packages/schemas/tables/users.sql b/packages/schemas/tables/users.sql index ab49a5605..67116429f 100644 --- a/packages/schemas/tables/users.sql +++ b/packages/schemas/tables/users.sql @@ -9,5 +9,6 @@ create table users ( password_encryption_method password_encryption_method, password_encryption_salt varchar(128), role_names jsonb /* @use RoleNames */ not null default '[]'::jsonb, + identities jsonb /* @use Identities */ not null default '{}'::jsonb, primary key (id) );