filter invalid humhub chars from username, fix export users

This commit is contained in:
einhornimmond 2024-10-22 14:07:10 +02:00
parent 675b3868a1
commit 56acc5846f
4 changed files with 62 additions and 21 deletions

View File

@ -50,7 +50,8 @@
"sodium-native": "^3.3.0",
"type-graphql": "^1.1.1",
"typed-rest-client": "^1.8.11",
"uuid": "^8.3.2"
"uuid": "^8.3.2",
"xregexp": "^5.1.1"
},
"devDependencies": {
"@eslint-community/eslint-plugin-eslint-comments": "^3.2.1",

View File

@ -9,9 +9,11 @@ import { checkDBVersion } from '@/typeorm/DBVersion'
import { HumHubClient } from './HumHubClient'
import { GetUser } from './model/GetUser'
import { UsersResponse } from './model/UsersResponse'
import { ExecutedHumhubAction, syncUser } from './syncUser'
const USER_BULK_SIZE = 20
const HUMHUB_BULK_SIZE = 50
function getUsersPage(page: number, limit: number): Promise<[User[], number]> {
return User.findAndCount({
@ -29,24 +31,28 @@ function getUsersPage(page: number, limit: number): Promise<[User[], number]> {
async function loadUsersFromHumHub(client: HumHubClient): Promise<Map<string, GetUser>> {
const start = new Date().getTime()
const humhubUsers = new Map<string, GetUser>()
const firstPage = await client.users(0, 50)
if (!firstPage) {
throw new LogError('not a single user found on humhub, please check config and setup')
}
firstPage.results.forEach((user) => {
humhubUsers.set(user.account.email.trim(), user)
})
let page = 1
while (humhubUsers.size < firstPage.total) {
const usersPage = await client.users(page, 50)
let page = 0
let skippedUsersCount = 0
let usersPage: UsersResponse | null = null
do {
usersPage = await client.users(page, HUMHUB_BULK_SIZE)
if (!usersPage) {
throw new LogError('error requesting next users page from humhub')
}
usersPage.results.forEach((user) => {
humhubUsers.set(user.account.email.trim(), user)
// deleted users have empty emails
if (user.account.email) {
humhubUsers.set(user.account.email.trim(), user)
} else {
skippedUsersCount++
}
})
page++
}
process.stdout.write(
`load users from humhub: ${humhubUsers.size}/${usersPage.total}, skipped: ${skippedUsersCount}\r`,
)
} while (usersPage && usersPage.results.length === HUMHUB_BULK_SIZE)
const elapsed = new Date().getTime() - start
logger.info('load users from humhub', {
total: humhubUsers.size,

View File

@ -1,16 +1,25 @@
import { User } from '@entity/User'
import XRegExp from 'xregexp'
import { PublishNameType } from '@/graphql/enum/PublishNameType'
import { LogError } from '@/server/LogError'
export class PublishNameLogic {
// allowed characters for humhub usernames
private usernameRegex: RegExp = XRegExp('[\\p{L}\\d_\\-@\\.]', 'g')
constructor(private user: User) {}
private firstUpperCaseSecondLowerCase(substring: string) {
if (!substring || substring.length < 2) {
throw new LogError('substring is to small, it need at least two characters', { substring })
private firstUpperCaseSecondLowerCase(name: string) {
if (name && name.length >= 2) {
return name.charAt(0).toUpperCase() + name.charAt(1).toLocaleLowerCase()
}
return substring.charAt(0).toUpperCase() + substring.charAt(1).toLocaleLowerCase()
return name
}
// remove character which are invalid for humhub username
private filterOutInvalidChar(name: string) {
// eslint-disable-next-line import/no-named-as-default-member
return XRegExp.match(name, this.usernameRegex, 'all').join('')
}
public hasAlias(): boolean {
@ -65,9 +74,9 @@ export class PublishNameLogic {
].includes(publishNameType)
) {
return publishNameType === PublishNameType.PUBLISH_NAME_ALIAS_OR_INITALS && this.hasAlias()
? this.user.alias
: this.firstUpperCaseSecondLowerCase(this.user.firstName) +
this.firstUpperCaseSecondLowerCase(this.user.lastName)
? this.filterOutInvalidChar(this.user.alias)
: this.firstUpperCaseSecondLowerCase(this.filterOutInvalidChar(this.user.firstName)) +
this.firstUpperCaseSecondLowerCase(this.filterOutInvalidChar(this.user.lastName))
}
return this.hasAlias() ? this.user.alias : this.user.gradidoID
}

View File

@ -324,6 +324,14 @@
dependencies:
"@babel/helper-plugin-utils" "^7.14.5"
"@babel/runtime-corejs3@^7.16.5":
version "7.25.7"
resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.25.7.tgz#29ca319b1272e9d78faa3f7ee891d0af63c53aa2"
integrity sha512-gMmIEhg35sXk9Te5qbGp3W9YKrvLt3HV658/d3odWrHSqT0JeG5OzsJWFHRLiOohRyjRsJc/x03DhJm3i8VJxg==
dependencies:
core-js-pure "^3.30.2"
regenerator-runtime "^0.14.0"
"@babel/runtime@^7.21.0":
version "7.22.5"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.22.5.tgz#8564dd588182ce0047d55d7a75e93921107b57ec"
@ -2340,6 +2348,11 @@ core-js-pure@^3.10.2:
resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.18.2.tgz#d8cc11d4885ea919f3de776d45e720e4c769d406"
integrity sha512-4hMMLUlZhKJKOWbbGD1/VDUxGPEhEoN/T01k7bx271WiBKCvCfkgPzy0IeRS4PB50p6/N1q/SZL4B/TRsTE5bA==
core-js-pure@^3.30.2:
version "3.38.1"
resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.38.1.tgz#e8534062a54b7221344884ba9b52474be495ada3"
integrity sha512-BY8Etc1FZqdw1glX0XNOq2FDwfrg/VGqoZOZCdaL+UmdaqDwQwYXkMJT4t6In+zfEfOJDcM9T0KdbBeJg8KKCQ==
core-util-is@~1.0.0:
version "1.0.3"
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85"
@ -6165,6 +6178,11 @@ regenerator-runtime@^0.13.11:
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9"
integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==
regenerator-runtime@^0.14.0:
version "0.14.1"
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz#356ade10263f685dda125100cd862c1db895327f"
integrity sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==
regexp-tree@~0.1.1:
version "0.1.27"
resolved "https://registry.yarnpkg.com/regexp-tree/-/regexp-tree-0.1.27.tgz#2198f0ef54518ffa743fe74d983b56ffd631b6cd"
@ -7395,6 +7413,13 @@ xmlchars@^2.2.0:
resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb"
integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==
xregexp@^5.1.1:
version "5.1.1"
resolved "https://registry.yarnpkg.com/xregexp/-/xregexp-5.1.1.tgz#6d3fe18819e3143aaf52f9284d34f49a59583ebb"
integrity sha512-fKXeVorD+CzWvFs7VBuKTYIW63YD1e1osxwQ8caZ6o1jg6pDAbABDG54LCIq0j5cy7PjRvGIq6sef9DYPXpncg==
dependencies:
"@babel/runtime-corejs3" "^7.16.5"
xss@^1.0.8:
version "1.0.10"
resolved "https://registry.yarnpkg.com/xss/-/xss-1.0.10.tgz#5cd63a9b147a755a14cb0455c7db8866120eb4d2"