mirror of
https://github.com/IT4Change/gradido.git
synced 2026-02-06 09:56:05 +00:00
startCommunityAuthentication refactored
This commit is contained in:
parent
ebd43543c6
commit
ed422fe293
@ -1,5 +1,14 @@
|
||||
import { CommunityLoggingView, Community as DbCommunity, FederatedCommunity as DbFederatedCommunity, FederatedCommunityLoggingView, getHomeCommunity } from 'database'
|
||||
import { validate as validateUUID, version as versionUUID } from 'uuid'
|
||||
import {
|
||||
CommunityHandshakeState as DbCommunityHandshakeState,
|
||||
CommunityHandshakeStateLoggingView,
|
||||
CommunityLoggingView,
|
||||
Community as DbCommunity,
|
||||
FederatedCommunity as DbFederatedCommunity,
|
||||
FederatedCommunityLoggingView,
|
||||
findPendingCommunityHandshake,
|
||||
getHomeCommunityWithFederatedCommunityOrFail,
|
||||
CommunityHandshakeStateType
|
||||
} from 'database'
|
||||
import { randombytes_random } from 'sodium-native'
|
||||
import { CONFIG as CONFIG_CORE } from 'core'
|
||||
|
||||
@ -11,65 +20,91 @@ import { communityAuthenticatedSchema, encryptAndSign, OpenConnectionJwtPayloadT
|
||||
import { getLogger } from 'log4js'
|
||||
import { AuthenticationClientFactory } from './client/AuthenticationClientFactory'
|
||||
import { EncryptedTransferArgs } from 'core'
|
||||
import { CommunityHandshakeStateLogic } from 'core'
|
||||
|
||||
const logger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.federation.authenticateCommunities`)
|
||||
const createLogger = (functionName: string) => getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.federation.authenticateCommunities.${functionName}`)
|
||||
|
||||
export async function startCommunityAuthentication(
|
||||
fedComB: DbFederatedCommunity,
|
||||
): Promise<void> {
|
||||
const methodLogger = getLogger(`${LOG4JS_BASE_CATEGORY_NAME}.federation.authenticateCommunities.startCommunityAuthentication`)
|
||||
const methodLogger = createLogger('startCommunityAuthentication')
|
||||
const handshakeID = randombytes_random().toString()
|
||||
methodLogger.addContext('handshakeID', handshakeID)
|
||||
methodLogger.debug(`startCommunityAuthentication()...`, {
|
||||
fedComB: new FederatedCommunityLoggingView(fedComB),
|
||||
})
|
||||
const homeComA = await getHomeCommunity()
|
||||
methodLogger.debug('homeComA', new CommunityLoggingView(homeComA!))
|
||||
const homeFedComA = await DbFederatedCommunity.findOneByOrFail({
|
||||
foreign: false,
|
||||
apiVersion: CONFIG_CORE.FEDERATION_BACKEND_SEND_ON_API,
|
||||
})
|
||||
methodLogger.debug('homeFedComA', new FederatedCommunityLoggingView(homeFedComA))
|
||||
const homeComA = await getHomeCommunityWithFederatedCommunityOrFail(fedComB.apiVersion)
|
||||
methodLogger.debug('homeComA', new CommunityLoggingView(homeComA))
|
||||
// check if result is like expected
|
||||
// TODO: use zod/valibot
|
||||
if (
|
||||
!homeComA.federatedCommunities ||
|
||||
homeComA.federatedCommunities.length === 0 ||
|
||||
homeComA.federatedCommunities[0].apiVersion !== fedComB.apiVersion
|
||||
) {
|
||||
throw new Error(`Missing home community or federated community with api version ${fedComB.apiVersion}`)
|
||||
}
|
||||
const homeFedComA = homeComA.federatedCommunities[0]
|
||||
const comB = await DbCommunity.findOneByOrFail({ publicKey: fedComB.publicKey })
|
||||
methodLogger.debug('started with comB:', new CommunityLoggingView(comB))
|
||||
// check if communityUuid is not a valid v4Uuid
|
||||
try {
|
||||
// communityAuthenticatedSchema.safeParse return true
|
||||
// - if communityUuid is a valid v4Uuid and
|
||||
// - if authenticatedAt is a valid date
|
||||
if (comB && !communityAuthenticatedSchema.safeParse(comB).success) {
|
||||
methodLogger.debug('comB.uuid is null or is a not valid v4Uuid...', comB.communityUuid || 'null', comB.authenticatedAt || 'null')
|
||||
const client = AuthenticationClientFactory.getInstance(fedComB)
|
||||
|
||||
if (client instanceof V1_0_AuthenticationClient) {
|
||||
if (!comB.publicJwtKey) {
|
||||
throw new Error('Public JWT key still not exist for comB ' + comB.name)
|
||||
}
|
||||
//create JWT with url in payload encrypted by foreignCom.publicJwtKey and signed with homeCom.privateJwtKey
|
||||
const payload = new OpenConnectionJwtPayloadType(handshakeID,
|
||||
ensureUrlEndsWithSlash(homeFedComA.endPoint).concat(homeFedComA.apiVersion),
|
||||
)
|
||||
methodLogger.debug('payload', payload)
|
||||
const jws = await encryptAndSign(payload, homeComA!.privateJwtKey!, comB.publicJwtKey!)
|
||||
methodLogger.debug('jws', jws)
|
||||
// prepare the args for the client invocation
|
||||
const args = new EncryptedTransferArgs()
|
||||
args.publicKey = homeComA!.publicKey.toString('hex')
|
||||
args.jwt = jws
|
||||
args.handshakeID = handshakeID
|
||||
methodLogger.debug('before client.openConnection() args:', args)
|
||||
const result = await client.openConnection(args)
|
||||
if (result) {
|
||||
methodLogger.debug(`successful initiated at community:`, fedComB.endPoint)
|
||||
} else {
|
||||
methodLogger.error(`can't initiate at community:`, fedComB.endPoint)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
methodLogger.debug(`comB.communityUuid is already a valid v4Uuid ${ comB.communityUuid || 'null' } and was authenticated at ${ comB.authenticatedAt || 'null'}`)
|
||||
}
|
||||
} catch (err) {
|
||||
methodLogger.error(`Error:`, err)
|
||||
|
||||
// communityAuthenticatedSchema.safeParse return true
|
||||
// - if communityUuid is a valid v4Uuid and
|
||||
// - if authenticatedAt is a valid date
|
||||
if (communityAuthenticatedSchema.safeParse(comB).success) {
|
||||
methodLogger.debug(`comB.communityUuid is already a valid v4Uuid ${ comB.communityUuid || 'null' } and was authenticated at ${ comB.authenticatedAt || 'null'}`)
|
||||
return
|
||||
}
|
||||
methodLogger.debug('comB.uuid is null or is a not valid v4Uuid...',
|
||||
comB.communityUuid || 'null', comB.authenticatedAt || 'null'
|
||||
)
|
||||
|
||||
// check if a authentication is already in progress
|
||||
const existingState = await findPendingCommunityHandshake(fedComB, false)
|
||||
if (existingState) {
|
||||
const logic = new CommunityHandshakeStateLogic(existingState)
|
||||
if (!await logic.isTimeoutUpdate()) {
|
||||
// authentication with community and api version is still in progress and it is not timeout yet
|
||||
methodLogger.debug('existingState', new CommunityHandshakeStateLoggingView(existingState))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
const state = new DbCommunityHandshakeState()
|
||||
state.publicKey = fedComB.publicKey
|
||||
state.apiVersion = fedComB.apiVersion
|
||||
state.status = CommunityHandshakeStateType.START_COMMUNITY_AUTHENTICATION
|
||||
state.handshakeId = parseInt(handshakeID)
|
||||
|
||||
const client = AuthenticationClientFactory.getInstance(fedComB)
|
||||
|
||||
if (client instanceof V1_0_AuthenticationClient) {
|
||||
if (!comB.publicJwtKey) {
|
||||
state.lastError = 'Public JWT key still not exist for comB ' + comB.name
|
||||
await state.save()
|
||||
throw new Error(state.lastError)
|
||||
}
|
||||
const stateSaveResolver = state.save()
|
||||
//create JWT with url in payload encrypted by foreignCom.publicJwtKey and signed with homeCom.privateJwtKey
|
||||
const payload = new OpenConnectionJwtPayloadType(handshakeID,
|
||||
ensureUrlEndsWithSlash(homeFedComA.endPoint).concat(homeFedComA.apiVersion),
|
||||
)
|
||||
methodLogger.debug('payload', payload)
|
||||
const jws = await encryptAndSign(payload, homeComA!.privateJwtKey!, comB.publicJwtKey!)
|
||||
methodLogger.debug('jws', jws)
|
||||
// prepare the args for the client invocation
|
||||
const args = new EncryptedTransferArgs()
|
||||
args.publicKey = homeComA!.publicKey.toString('hex')
|
||||
args.jwt = jws
|
||||
args.handshakeID = handshakeID
|
||||
await stateSaveResolver
|
||||
methodLogger.debug('before client.openConnection() args:', args)
|
||||
const result = await client.openConnection(args)
|
||||
if (result) {
|
||||
methodLogger.info(`successful initiated at community:`, fedComB.endPoint)
|
||||
} else {
|
||||
methodLogger.error(`can't initiate at community:`, fedComB.endPoint)
|
||||
}
|
||||
}
|
||||
methodLogger.removeContext('handshakeID')
|
||||
}
|
||||
|
||||
@ -22,4 +22,5 @@ export * from './util/calculateSenderBalance'
|
||||
export * from './util/utilities'
|
||||
export * from './validation/user'
|
||||
export * from './config/index'
|
||||
export * from './logic'
|
||||
|
||||
|
||||
22
core/src/logic/CommunityHandshakeState.logic.ts
Normal file
22
core/src/logic/CommunityHandshakeState.logic.ts
Normal file
@ -0,0 +1,22 @@
|
||||
import { CommunityHandshakeState, CommunityHandshakeStateType } from 'database'
|
||||
import { FEDERATION_AUTHENTICATION_TIMEOUT_MS } from 'shared'
|
||||
|
||||
export class CommunityHandshakeStateLogic {
|
||||
public constructor(private communityHandshakeStateEntity: CommunityHandshakeState) {}
|
||||
|
||||
/**
|
||||
* Check for expired state and if not, check timeout and update (write into db) to expired state
|
||||
* @returns true if the community handshake state is expired
|
||||
*/
|
||||
public async isTimeoutUpdate(): Promise<boolean> {
|
||||
if (this.communityHandshakeStateEntity.status === CommunityHandshakeStateType.EXPIRED) {
|
||||
return true
|
||||
}
|
||||
if (Date.now() - this.communityHandshakeStateEntity.updatedAt.getTime() > FEDERATION_AUTHENTICATION_TIMEOUT_MS) {
|
||||
this.communityHandshakeStateEntity.status = CommunityHandshakeStateType.EXPIRED
|
||||
await this.communityHandshakeStateEntity.save()
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
1
core/src/logic/index.ts
Normal file
1
core/src/logic/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export { CommunityHandshakeStateLogic } from './CommunityHandshakeState.logic'
|
||||
@ -5,12 +5,13 @@ export async function upgrade(queryFn: (query: string, values?: any[]) => Promis
|
||||
handshake_id int unsigned NOT NULL,
|
||||
one_time_code int unsigned NOT NULL,
|
||||
public_key binary(32) NOT NULL,
|
||||
api_version varchar(255) NOT NULL,
|
||||
status varchar(255) NOT NULL DEFAULT 'OPEN_CONNECTION',
|
||||
last_error text,
|
||||
created_at datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
updated_at datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
|
||||
PRIMARY KEY (id),
|
||||
KEY idx_public_key (public_key),
|
||||
KEY idx_public_key (public_key)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;`)
|
||||
}
|
||||
|
||||
|
||||
@ -16,10 +16,13 @@ export class CommunityHandshakeState extends BaseEntity {
|
||||
@Column({ name: 'public_key', type: 'binary', length: 32 })
|
||||
publicKey: Buffer
|
||||
|
||||
@Column({ name: 'api_version', type: 'varchar', length: 255 })
|
||||
apiVersion: string
|
||||
|
||||
@Column({
|
||||
type: 'varchar',
|
||||
length: 255,
|
||||
default: CommunityHandshakeStateType.OPEN_CONNECTION,
|
||||
default: CommunityHandshakeStateType.START_COMMUNITY_AUTHENTICATION,
|
||||
nullable: false,
|
||||
})
|
||||
status: CommunityHandshakeStateType
|
||||
|
||||
@ -19,6 +19,7 @@ import { UserRole } from './UserRole'
|
||||
|
||||
export {
|
||||
Community,
|
||||
CommunityHandshakeState,
|
||||
Contribution,
|
||||
ContributionLink,
|
||||
ContributionMessage,
|
||||
@ -26,8 +27,7 @@ export {
|
||||
Event,
|
||||
FederatedCommunity,
|
||||
LoginElopageBuys,
|
||||
Migration,
|
||||
CommunityHandshakeState,
|
||||
Migration,
|
||||
ProjectBranding,
|
||||
OpenaiThreads,
|
||||
PendingTransaction,
|
||||
@ -40,6 +40,7 @@ export {
|
||||
|
||||
export const entities = [
|
||||
Community,
|
||||
CommunityHandshakeState,
|
||||
Contribution,
|
||||
ContributionLink,
|
||||
ContributionMessage,
|
||||
@ -48,7 +49,6 @@ export const entities = [
|
||||
FederatedCommunity,
|
||||
LoginElopageBuys,
|
||||
Migration,
|
||||
CommunityHandshakeState,
|
||||
ProjectBranding,
|
||||
OpenaiThreads,
|
||||
PendingTransaction,
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
export enum CommunityHandshakeStateType {
|
||||
START_COMMUNITY_AUTHENTICATION = 'START_COMMUNITY_AUTHENTICATION',
|
||||
OPEN_CONNECTION = 'OPEN_CONNECTION',
|
||||
OPEN_CONNECTION_CALLBACK = 'OPEN_CONNECTION_CALLBACK',
|
||||
|
||||
|
||||
@ -1,63 +1,7 @@
|
||||
import { latestDbVersion } from './detectLastDBVersion'
|
||||
import { Community } from './entity/Community'
|
||||
import { Contribution } from './entity/Contribution'
|
||||
import { ContributionLink } from './entity/ContributionLink'
|
||||
import { ContributionMessage } from './entity/ContributionMessage'
|
||||
import { DltTransaction } from './entity/DltTransaction'
|
||||
import { Event } from './entity/Event'
|
||||
import { FederatedCommunity } from './entity/FederatedCommunity'
|
||||
import { LoginElopageBuys } from './entity/LoginElopageBuys'
|
||||
import { Migration } from './entity/Migration'
|
||||
import { OpenaiThreads } from './entity/OpenaiThreads'
|
||||
import { PendingTransaction } from './entity/PendingTransaction'
|
||||
import { ProjectBranding } from './entity/ProjectBranding'
|
||||
import { Transaction } from './entity/Transaction'
|
||||
import { TransactionLink } from './entity/TransactionLink'
|
||||
import { User } from './entity/User'
|
||||
import { UserContact } from './entity/UserContact'
|
||||
import { UserRole } from './entity/UserRole'
|
||||
|
||||
export {
|
||||
Community,
|
||||
Contribution,
|
||||
ContributionLink,
|
||||
ContributionMessage,
|
||||
DltTransaction,
|
||||
Event,
|
||||
FederatedCommunity,
|
||||
LoginElopageBuys,
|
||||
Migration,
|
||||
ProjectBranding,
|
||||
OpenaiThreads,
|
||||
PendingTransaction,
|
||||
Transaction,
|
||||
TransactionLink,
|
||||
User,
|
||||
UserContact,
|
||||
UserRole,
|
||||
}
|
||||
|
||||
export const entities = [
|
||||
Community,
|
||||
Contribution,
|
||||
ContributionLink,
|
||||
ContributionMessage,
|
||||
DltTransaction,
|
||||
Event,
|
||||
FederatedCommunity,
|
||||
LoginElopageBuys,
|
||||
Migration,
|
||||
ProjectBranding,
|
||||
OpenaiThreads,
|
||||
PendingTransaction,
|
||||
Transaction,
|
||||
TransactionLink,
|
||||
User,
|
||||
UserContact,
|
||||
UserRole,
|
||||
]
|
||||
|
||||
export { latestDbVersion }
|
||||
|
||||
export * from './entity'
|
||||
export * from './logging'
|
||||
export * from './queries'
|
||||
export * from './util'
|
||||
|
||||
25
database/src/logging/CommunityHandshakeStateLogging.view.ts
Normal file
25
database/src/logging/CommunityHandshakeStateLogging.view.ts
Normal file
@ -0,0 +1,25 @@
|
||||
import { CommunityHandshakeState } from '..'
|
||||
import { AbstractLoggingView } from './AbstractLogging.view'
|
||||
import { FederatedCommunityLoggingView } from './FederatedCommunityLogging.view'
|
||||
|
||||
export class CommunityHandshakeStateLoggingView extends AbstractLoggingView {
|
||||
public constructor(private self: CommunityHandshakeState) {
|
||||
super()
|
||||
}
|
||||
|
||||
public toJSON(): any {
|
||||
return {
|
||||
id: this.self.id,
|
||||
handshakeId: this.self.handshakeId,
|
||||
oneTimeCode: this.self.oneTimeCode,
|
||||
publicKey: this.self.publicKey.toString(this.bufferStringFormat),
|
||||
status: this.self.status,
|
||||
lastError: this.self.lastError,
|
||||
createdAt: this.dateToString(this.self.createdAt),
|
||||
updatedAt: this.dateToString(this.self.updatedAt),
|
||||
federatedCommunity: this.self.federatedCommunity
|
||||
? new FederatedCommunityLoggingView(this.self.federatedCommunity)
|
||||
: undefined,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,5 @@
|
||||
import { Community } from '../entity'
|
||||
|
||||
import { FederatedCommunityLoggingView } from './FederatedCommunityLogging.view'
|
||||
import { AbstractLoggingView } from './AbstractLogging.view'
|
||||
|
||||
export class CommunityLoggingView extends AbstractLoggingView {
|
||||
@ -21,6 +21,9 @@ export class CommunityLoggingView extends AbstractLoggingView {
|
||||
creationDate: this.dateToString(this.self.creationDate),
|
||||
createdAt: this.dateToString(this.self.createdAt),
|
||||
updatedAt: this.dateToString(this.self.updatedAt),
|
||||
federatedCommunities: this.self.federatedCommunities?.map(
|
||||
(federatedCommunity) => new FederatedCommunityLoggingView(federatedCommunity)
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -11,6 +11,7 @@ import { TransactionLoggingView } from './TransactionLogging.view'
|
||||
import { UserContactLoggingView } from './UserContactLogging.view'
|
||||
import { UserLoggingView } from './UserLogging.view'
|
||||
import { UserRoleLoggingView } from './UserRoleLogging.view'
|
||||
import { CommunityHandshakeStateLoggingView } from './CommunityHandshakeStateLogging.view'
|
||||
|
||||
export {
|
||||
AbstractLoggingView,
|
||||
@ -24,6 +25,7 @@ export {
|
||||
UserContactLoggingView,
|
||||
UserLoggingView,
|
||||
UserRoleLoggingView,
|
||||
CommunityHandshakeStateLoggingView,
|
||||
}
|
||||
|
||||
export const logger = getLogger(LOG4JS_BASE_CATEGORY_NAME)
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { Community as DbCommunity, FederatedCommunity as DbFederatedCommunity } from '..'
|
||||
import { AppDatabase } from '../AppDatabase'
|
||||
import { getHomeCommunity, getReachableCommunities } from './communities'
|
||||
import { getHomeCommunity, getHomeCommunityWithFederatedCommunityOrFail, getReachableCommunities } from './communities'
|
||||
import { describe, expect, it, beforeEach, beforeAll, afterAll } from 'vitest'
|
||||
import { createCommunity, createVerifiedFederatedCommunity } from '../seeds/community'
|
||||
|
||||
@ -39,6 +39,24 @@ describe('community.queries', () => {
|
||||
expect(community?.privateKey).toStrictEqual(homeCom.privateKey)
|
||||
})
|
||||
})
|
||||
describe('getHomeCommunityWithFederatedCommunityOrFail', () => {
|
||||
it('should return the home community with federated communities', async () => {
|
||||
const homeCom = await createCommunity(false)
|
||||
await createVerifiedFederatedCommunity('1_0', 100, homeCom)
|
||||
const community = await getHomeCommunityWithFederatedCommunityOrFail('1_0')
|
||||
expect(community).toBeDefined()
|
||||
expect(community?.federatedCommunities).toHaveLength(1)
|
||||
})
|
||||
|
||||
it('should throw if no home community exists', async () => {
|
||||
expect(() => getHomeCommunityWithFederatedCommunityOrFail('1_0')).rejects.toThrow()
|
||||
})
|
||||
|
||||
it('should throw if no federated community exists', async () => {
|
||||
await createCommunity(false)
|
||||
expect(() => getHomeCommunityWithFederatedCommunityOrFail('1_0')).rejects.toThrow()
|
||||
})
|
||||
})
|
||||
describe('getReachableCommunities', () => {
|
||||
it('home community counts also to reachable communities', async () => {
|
||||
await createCommunity(false)
|
||||
|
||||
@ -10,7 +10,14 @@ export async function getHomeCommunity(): Promise<DbCommunity | null> {
|
||||
// TODO: Put in Cache, it is needed nearly always
|
||||
// TODO: return only DbCommunity or throw to reduce unnecessary checks, because there should be always a home community
|
||||
return await DbCommunity.findOne({
|
||||
where: { foreign: false },
|
||||
where: { foreign: false }
|
||||
})
|
||||
}
|
||||
|
||||
export async function getHomeCommunityWithFederatedCommunityOrFail(apiVersion: string): Promise<DbCommunity> {
|
||||
return await DbCommunity.findOneOrFail({
|
||||
where: { foreign: false, federatedCommunities: { apiVersion } },
|
||||
relations: { federatedCommunities: true },
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
15
database/src/queries/communityHandshakes.ts
Normal file
15
database/src/queries/communityHandshakes.ts
Normal file
@ -0,0 +1,15 @@
|
||||
import { CommunityHandshakeState } from '../entity'
|
||||
import { FederatedCommunity } from '../entity/FederatedCommunity'
|
||||
|
||||
/**
|
||||
* Find a pending community handshake by public key.
|
||||
* @param publicKey The public key of the community.
|
||||
* @param withRelations Whether to include the federated community and community in the result, default true.
|
||||
* @returns The CommunityHandshakeState with associated federated community and community.
|
||||
*/
|
||||
export function findPendingCommunityHandshake(federatedCommunity: FederatedCommunity, withRelations = true): Promise<CommunityHandshakeState | null> {
|
||||
return CommunityHandshakeState.findOne({
|
||||
where: { publicKey: federatedCommunity.publicKey, apiVersion: federatedCommunity.apiVersion },
|
||||
relations: withRelations ? { federatedCommunity: { community: true } } : undefined,
|
||||
})
|
||||
}
|
||||
@ -5,5 +5,6 @@ export * from './communities'
|
||||
export * from './pendingTransactions'
|
||||
export * from './transactions'
|
||||
export * from './transactionLinks'
|
||||
export * from './communityHandshakes'
|
||||
|
||||
export const LOG4JS_QUERIES_CATEGORY_NAME = `${LOG4JS_BASE_CATEGORY_NAME}.queries`
|
||||
|
||||
@ -2,7 +2,13 @@ import { Community, FederatedCommunity } from '../entity'
|
||||
import { randomBytes } from 'node:crypto'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
|
||||
export async function createCommunity(foreign: boolean, save: boolean = true): Promise<Community> {
|
||||
/**
|
||||
* Creates a community.
|
||||
* @param foreign
|
||||
* @param store if true, write to db, default: true
|
||||
* @returns
|
||||
*/
|
||||
export async function createCommunity(foreign: boolean, store: boolean = true): Promise<Community> {
|
||||
const community = new Community()
|
||||
community.publicKey = randomBytes(32)
|
||||
community.communityUuid = uuidv4()
|
||||
@ -23,14 +29,22 @@ export async function createCommunity(foreign: boolean, save: boolean = true): P
|
||||
community.description = 'HomeCommunity-description'
|
||||
community.url = 'http://localhost/api'
|
||||
}
|
||||
return save ? await community.save() : community
|
||||
return store ? await community.save() : community
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a verified federated community.
|
||||
* @param apiVersion
|
||||
* @param verifiedBeforeMs time in ms before the current time
|
||||
* @param community
|
||||
* @param store if true, write to db, default: true
|
||||
* @returns
|
||||
*/
|
||||
export async function createVerifiedFederatedCommunity(
|
||||
apiVersion: string,
|
||||
verifiedBeforeMs: number,
|
||||
community: Community,
|
||||
save: boolean = true
|
||||
store: boolean = true
|
||||
): Promise<FederatedCommunity> {
|
||||
const federatedCommunity = new FederatedCommunity()
|
||||
federatedCommunity.apiVersion = apiVersion
|
||||
@ -38,5 +52,5 @@ export async function createVerifiedFederatedCommunity(
|
||||
federatedCommunity.publicKey = community.publicKey
|
||||
federatedCommunity.community = community
|
||||
federatedCommunity.verifiedAt = new Date(Date.now() - verifiedBeforeMs)
|
||||
return save ? await federatedCommunity.save() : federatedCommunity
|
||||
return store ? await federatedCommunity.save() : federatedCommunity
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user