Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import NoteRepository from '../noteRepository'
import OrganizationRepository from '../organizationRepository'
import TagRepository from '../tagRepository'
import TaskRepository from '../taskRepository'
import lodash from 'lodash'

const db = null

Expand Down Expand Up @@ -66,7 +67,8 @@ describe('MemberRepository tests', () => {
joinedAt: '2020-05-27T15:13:30Z',
}

const memberCreated = await MemberRepository.create(member2add, mockIRepositoryOptions)
const cloned = lodash.cloneDeep(member2add)
const memberCreated = await MemberRepository.create(cloned, mockIRepositoryOptions)

// Trim the hour part from timestamp so we can atleast test if the day is correct for createdAt and joinedAt
memberCreated.createdAt = memberCreated.createdAt.toISOString().split('T')[0]
Expand Down Expand Up @@ -147,7 +149,8 @@ describe('MemberRepository tests', () => {
joinedAt: '2020-05-27T15:13:30Z',
}

const memberCreated = await MemberRepository.create(member2add, mockIRepositoryOptions, false)
const cloned = lodash.cloneDeep(member2add)
const memberCreated = await MemberRepository.create(cloned, mockIRepositoryOptions, false)

// Trim the hour part from timestamp so we can atleast test if the day is correct for createdAt and joinedAt
memberCreated.createdAt = memberCreated.createdAt.toISOString().split('T')[0]
Expand Down Expand Up @@ -190,7 +193,8 @@ describe('MemberRepository tests', () => {
joinedAt: '2020-05-27T15:13:30Z',
}

const memberCreated = await MemberRepository.create(member2add, mockIRepositoryOptions)
const cloned = lodash.cloneDeep(member2add)
const memberCreated = await MemberRepository.create(cloned, mockIRepositoryOptions)

// Trim the hour part from timestamp so we can atleast test if the day is correct for createdAt and joinedAt
memberCreated.createdAt = memberCreated.createdAt.toISOString().split('T')[0]
Expand Down Expand Up @@ -357,7 +361,8 @@ describe('MemberRepository tests', () => {
joinedAt: '2020-05-27T15:13:30Z',
}

const memberCreated = await MemberRepository.create(member2add, mockIRepositoryOptions)
const cloned = lodash.cloneDeep(member2add)
const memberCreated = await MemberRepository.create(cloned, mockIRepositoryOptions)

const expectedMemberFound = {
id: memberCreated.id,
Expand Down Expand Up @@ -419,7 +424,8 @@ describe('MemberRepository tests', () => {
joinedAt: '2020-05-27T15:13:30Z',
}

const memberCreated = await MemberRepository.create(member2add, mockIRepositoryOptions)
const cloned = lodash.cloneDeep(member2add)
const memberCreated = await MemberRepository.create(cloned, mockIRepositoryOptions)

const expectedMemberFound = {
id: memberCreated.id,
Expand Down Expand Up @@ -2636,7 +2642,8 @@ describe('MemberRepository tests', () => {
score: '1',
joinedAt: '2021-05-27T15:14:30Z',
}
const returnedMember = await MemberRepository.create(member1, mockIRepositoryOptions)
let cloned = lodash.cloneDeep(member1)
const returnedMember = await MemberRepository.create(cloned, mockIRepositoryOptions)

const updateFields = {
username: {
Expand Down Expand Up @@ -2671,9 +2678,10 @@ describe('MemberRepository tests', () => {
location: 'Istanbul',
}

cloned = lodash.cloneDeep(updateFields)
const updatedMember = await MemberRepository.update(
returnedMember.id,
updateFields,
cloned,
mockIRepositoryOptions,
)

Expand Down
25 changes: 8 additions & 17 deletions backend/src/database/repositories/__tests__/taskRepository.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import MemberRepository from '../memberRepository'
import ActivityRepository from '../activityRepository'
import { PlatformType } from '../../../types/integrationEnums'
import { generateUUIDv1 } from '../../../utils/uuid'
import lodash from 'lodash'

const db = null

Expand Down Expand Up @@ -78,12 +79,11 @@ async function getToCreate(task, options, from = { fromMembers: [], fromActiviti
task.assignees = []

for (const sampleMember of fromMembers) {
task.members.push((await MemberRepository.create(sampleMember, options)).id)
const cloned = lodash.cloneDeep(sampleMember)
task.members.push((await MemberRepository.create(cloned, options)).id)
}

for (const sampleActivity of fromActivities) {
let username: string

const existing = await MemberRepository.memberExists(
sampleMembers[0].username[PlatformType.GITHUB].username,
PlatformType.GITHUB,
Expand All @@ -92,24 +92,15 @@ async function getToCreate(task, options, from = { fromMembers: [], fromActiviti

if (existing) {
sampleActivity.member = existing.id
username = sampleMembers[0].username[PlatformType.GITHUB].username
sampleActivity.username = sampleMembers[0].username[PlatformType.GITHUB].username
} else {
const member = await MemberRepository.create(sampleMembers[0], options)
const cloned = lodash.cloneDeep(sampleMembers[0])
const member = await MemberRepository.create(cloned, options)
sampleActivity.member = member.id
username = sampleMembers[0].username[PlatformType.GITHUB].username
sampleActivity.username = sampleMembers[0].username[PlatformType.GITHUB].username
}

task.activities.push(
(
await ActivityRepository.create(
{
...sampleActivity,
username,
},
options,
)
).id,
)
task.activities.push((await ActivityRepository.create(sampleActivity, options)).id)
}
task.assignees.push(options.currentUser.id)
return task
Expand Down
100 changes: 53 additions & 47 deletions backend/src/database/repositories/memberRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,12 @@ import RawQueryParser from './filters/rawQueryParser'
import SequelizeRepository from './sequelizeRepository'
import SettingsRepository from './settingsRepository'
import TenantRepository from './tenantRepository'
import { IActiveMemberData, IActiveMemberFilter, IMemberIdentity } from './types/memberTypes'
import {
IActiveMemberData,
IActiveMemberFilter,
IMemberIdentity,
mapUsernameToIdentities,
} from './types/memberTypes'

const { Op } = Sequelize

Expand All @@ -35,14 +40,7 @@ class MemberRepository {
throw new Error('Username object does not have any platforms!')
}

// fix legacy calls
for (const platform of platforms) {
if (typeof data.username[platform] === 'string') {
data.username[platform] = {
username: data.username[platform],
}
}
}
data.username = mapUsernameToIdentities(data.username)

const currentUser = SequelizeRepository.getCurrentUser(options)

Expand Down Expand Up @@ -82,19 +80,21 @@ class MemberRepository {
`

for (const platform of Object.keys(username) as PlatformType[]) {
const identity = username[platform]
await seq.query(query, {
replacements: {
memberId: record.id,
platform,
username: identity.username,
sourceId: identity.sourceId || null,
integrationId: identity.integrationId || null,
tenantId: tenant.id,
},
type: QueryTypes.INSERT,
transaction,
})
const identities: any[] = username[platform]
for (const identity of identities) {
await seq.query(query, {
replacements: {
memberId: record.id,
platform,
username: identity.username,
sourceId: identity.sourceId || null,
integrationId: identity.integrationId || null,
tenantId: tenant.id,
},
type: QueryTypes.INSERT,
transaction,
})
}
}

await record.setActivities(data.activities || [], {
Expand Down Expand Up @@ -374,15 +374,26 @@ class MemberRepository {
inner join identities i on i."memberId" = m.id
where mi."tenantId" = :tenantId
and mi.platform = :platform
and mi.username = :username
and mi.username in (:usernames)
`

const usernames: string[] = []
if (typeof username === 'string') {
usernames.push(username)
} else if (Array.isArray(username)) {
usernames.push(...username)
} else {
throw new Error(
'Unknown username format! Allowed formats are string or string[]. For example: "username" or ["username1", "username2"]',
)
}

const records = await options.database.sequelize.query(query, {
type: Sequelize.QueryTypes.SELECT,
replacements: {
tenantId: currentTenant.id,
platform,
username,
usernames,
},
transaction,
model: options.database.member,
Expand Down Expand Up @@ -483,36 +494,31 @@ class MemberRepository {
if (data.username) {
const platforms = Object.keys(data.username) as PlatformType[]
if (platforms.length > 0) {
// fix legacy calls
for (const platform of platforms) {
if (typeof data.username[platform] === 'string') {
data.username[platform] = {
username: data.username[platform],
}
}
}
data.username = mapUsernameToIdentities(data.username)

const seq = SequelizeRepository.getSequelize(options)
const query = `
insert into "memberIdentities"("memberId", platform, username, "sourceId", "tenantId", "integrationId")
values (:memberId, :platform, :username, :sourceId, :tenantId, :integrationId);
`

for (const platform of Object.keys(data.username) as PlatformType[]) {
const identity = data.username[platform]

await seq.query(query, {
replacements: {
memberId: record.id,
platform,
username: identity.username,
sourceId: identity.sourceId || null,
integrationId: identity.integrationId || null,
tenantId: currentTenant.id,
},
type: QueryTypes.INSERT,
transaction,
})
for (const platform of platforms) {
const identities = data.username[platform]

for (const identity of identities) {
await seq.query(query, {
replacements: {
memberId: record.id,
platform,
username: identity.username,
sourceId: identity.sourceId || null,
integrationId: identity.integrationId || null,
tenantId: currentTenant.id,
},
type: QueryTypes.INSERT,
transaction,
})
}
}
}
}
Expand Down
42 changes: 42 additions & 0 deletions backend/src/database/repositories/types/memberTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,45 @@ export interface IMemberIdentity {
sourceId?: string
createdAt: string
}

export const mapSingleUsernameToIdentity = (usernameOrIdentity: any): any => {
if (typeof usernameOrIdentity === 'string') {
return {
username: usernameOrIdentity,
}
}

if (typeof usernameOrIdentity === 'object') {
return usernameOrIdentity
}

throw new Error(`Unknown username type: ${typeof usernameOrIdentity}: ${usernameOrIdentity}`)
}

export const mapUsernameToIdentities = (username: any, platform?: string): any => {
const mapped = {}

if (typeof username === 'string') {
if (!platform) {
throw new Error('Platform is required when username is a string')
}

mapped[platform] = [mapSingleUsernameToIdentity(username)]
} else {
for (const platform of Object.keys(username)) {
const data = username[platform]

if (Array.isArray(data)) {
const identities = []
for (const entry of data) {
identities.push(mapSingleUsernameToIdentity(entry))
}
mapped[platform] = identities
} else {
mapped[platform] = [mapSingleUsernameToIdentity(data)]
}
}
}

return mapped
}
Original file line number Diff line number Diff line change
Expand Up @@ -416,8 +416,15 @@ export class DiscordIntegrationService extends IntegrationServiceBase {
type: 'joined_guild',
sourceId,
timestamp: joinedAt,
username,
member: {
username,
username: {
[PlatformType.DISCORD]: {
username,
integrationId: context.integration.id,
sourceId: record.user.id,
},
},
attributes: {
[MemberAttributeName.SOURCE_ID]: {
[PlatformType.DISCORD]: record.user.id,
Expand Down Expand Up @@ -546,8 +553,14 @@ export class DiscordIntegrationService extends IntegrationServiceBase {
attachments: record.attachments ? record.attachments : [],
forum: isForum,
},
username,
member: {
username,
username: {
[PlatformType.DISCORD]: {
username,
integrationId: context.integration.id,
},
},
attributes: {
[MemberAttributeName.SOURCE_ID]: {
[PlatformType.DISCORD]: record.author.id,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,7 @@ export class TwitterIntegrationService extends IntegrationServiceBase {
): Array<AddActivitiesSingle> {
return records.map((record) => {
const out: any = {
username: record.member.username,
tenant: context.integration.tenantId,
platform: PlatformType.TWITTER,
type: stream.value === 'mentions' ? 'mention' : 'hashtag',
Expand Down
4 changes: 3 additions & 1 deletion backend/src/services/__tests__/memberService.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import SettingsRepository from '../../database/repositories/settingsRepository'
import OrganizationService from '../organizationService'
import Plans from '../../security/plans'
import { generateUUIDv1 } from '../../utils/uuid'
import lodash from 'lodash'

const db = null

Expand Down Expand Up @@ -1869,7 +1870,8 @@ describe('MemberService tests', () => {
attributes: {},
}

const returnedMember1 = await MemberRepository.create(member1, mockIRepositoryOptions)
const cloned = lodash.cloneDeep(member1)
const returnedMember1 = await MemberRepository.create(cloned, mockIRepositoryOptions)
delete returnedMember1.toMerge
delete returnedMember1.noMerge
delete returnedMember1.tags
Expand Down
Loading