mirror of
https://github.com/IT4Change/gradido.git
synced 2026-02-06 09:56:05 +00:00
Merge branch 'master' into overview_circles
This commit is contained in:
commit
8abd5404bf
@ -1,4 +1,3 @@
|
||||
import { User } from '@entity/User'
|
||||
import { SignJWT } from 'jose'
|
||||
import { IRequestOptions, IRestResponse, RestClient } from 'typed-rest-client'
|
||||
|
||||
@ -6,6 +5,7 @@ import { CONFIG } from '@/config'
|
||||
import { LogError } from '@/server/LogError'
|
||||
import { backendLogger as logger } from '@/server/logger'
|
||||
|
||||
import { PostUserLoggingView } from './logging/PostUserLogging.view'
|
||||
import { GetUser } from './model/GetUser'
|
||||
import { PostUser } from './model/PostUser'
|
||||
import { UsersResponse } from './model/UsersResponse'
|
||||
@ -59,9 +59,8 @@ export class HumHubClient {
|
||||
return token
|
||||
}
|
||||
|
||||
public async createAutoLoginUrl(user: User) {
|
||||
public async createAutoLoginUrl(username: string) {
|
||||
const secret = new TextEncoder().encode(CONFIG.HUMHUB_JWT_KEY)
|
||||
const username = user.alias ?? user.gradidoID
|
||||
logger.info(`user ${username} as username for humhub auto-login`)
|
||||
const token = await new SignJWT({ username })
|
||||
.setProtectedHeader({ alg: 'HS256' })
|
||||
@ -109,6 +108,11 @@ export class HumHubClient {
|
||||
return this.restClient.get<GetUser>('/api/v1/user/get-by-email', options)
|
||||
}
|
||||
|
||||
public async userByUsernameAsync(username: string): Promise<IRestResponse<GetUser>> {
|
||||
const options = await this.createRequestOptions({ username })
|
||||
return this.restClient.get<GetUser>('/api/v1/user/get-by-username', options)
|
||||
}
|
||||
|
||||
/**
|
||||
* get user by username
|
||||
* https://marketplace.humhub.com/module/rest/docs/html/user.html#tag/User/paths/~1user~1get-by-username/get
|
||||
@ -130,7 +134,7 @@ export class HumHubClient {
|
||||
* @param user for saving on humhub instance
|
||||
*/
|
||||
public async createUser(user: PostUser): Promise<void> {
|
||||
logger.info('create new humhub user', user)
|
||||
logger.info('create new humhub user', new PostUserLoggingView(user))
|
||||
const options = await this.createRequestOptions()
|
||||
try {
|
||||
const response = await this.restClient.create('/api/v1/user', user, options)
|
||||
@ -153,7 +157,7 @@ export class HumHubClient {
|
||||
* @returns updated user object on success
|
||||
*/
|
||||
public async updateUser(user: PostUser, humhubUserId: number): Promise<GetUser | null> {
|
||||
logger.info('update humhub user', user)
|
||||
logger.info('update humhub user', new PostUserLoggingView(user))
|
||||
const options = await this.createRequestOptions()
|
||||
const response = await this.restClient.update<GetUser>(
|
||||
`/api/v1/user/${humhubUserId}`,
|
||||
|
||||
18
backend/src/apis/humhub/logging/AccountLogging.view.ts
Normal file
18
backend/src/apis/humhub/logging/AccountLogging.view.ts
Normal file
@ -0,0 +1,18 @@
|
||||
import { AbstractLoggingView } from '@logging/AbstractLogging.view'
|
||||
|
||||
import { Account } from '@/apis/humhub/model/Account'
|
||||
|
||||
export class AccountLoggingView extends AbstractLoggingView {
|
||||
public constructor(private self: Account) {
|
||||
super()
|
||||
}
|
||||
|
||||
public toJSON(): Account {
|
||||
return {
|
||||
username: this.self.username.substring(0, 3) + '...',
|
||||
email: this.self.email.substring(0, 3) + '...',
|
||||
language: this.self.language,
|
||||
status: this.self.status,
|
||||
}
|
||||
}
|
||||
}
|
||||
23
backend/src/apis/humhub/logging/PostUserLogging.view.ts
Normal file
23
backend/src/apis/humhub/logging/PostUserLogging.view.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import { AbstractLoggingView } from '@logging/AbstractLogging.view'
|
||||
|
||||
import { PostUser } from '@/apis/humhub/model/PostUser'
|
||||
|
||||
import { AccountLoggingView } from './AccountLogging.view'
|
||||
import { ProfileLoggingView } from './ProfileLogging.view'
|
||||
|
||||
export class PostUserLoggingView extends AbstractLoggingView {
|
||||
public constructor(private self: PostUser) {
|
||||
super()
|
||||
}
|
||||
|
||||
public toJSON(): PostUser {
|
||||
return {
|
||||
account: new AccountLoggingView(this.self.account).toJSON(),
|
||||
profile: new ProfileLoggingView(this.self.profile).toJSON(),
|
||||
password: {
|
||||
newPassword: '',
|
||||
mustChangePassword: false,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
20
backend/src/apis/humhub/logging/ProfileLogging.view.ts
Normal file
20
backend/src/apis/humhub/logging/ProfileLogging.view.ts
Normal file
@ -0,0 +1,20 @@
|
||||
import { AbstractLoggingView } from '@logging/AbstractLogging.view'
|
||||
|
||||
import { Profile } from '@/apis/humhub/model/Profile'
|
||||
|
||||
export class ProfileLoggingView extends AbstractLoggingView {
|
||||
public constructor(private self: Profile) {
|
||||
super()
|
||||
}
|
||||
|
||||
public toJSON(): Profile {
|
||||
const gradidoAddressParts = this.self.gradido_address.split('/')
|
||||
return {
|
||||
firstname: this.self.firstname.substring(0, 3) + '...',
|
||||
lastname: this.self.lastname.substring(0, 3) + '...',
|
||||
// eslint-disable-next-line camelcase
|
||||
gradido_address:
|
||||
gradidoAddressParts[0] + '/' + gradidoAddressParts[1].substring(0, 3) + '...',
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -168,7 +168,7 @@ export class UserResolver {
|
||||
let humhubUserPromise: Promise<IRestResponse<GetUser>> | undefined
|
||||
const klicktippStatePromise = getKlicktippState(dbUser.emailContact.email)
|
||||
if (CONFIG.HUMHUB_ACTIVE && dbUser.humhubAllowed) {
|
||||
humhubUserPromise = HumHubClient.getInstance()?.userByEmailAsync(email)
|
||||
humhubUserPromise = HumHubClient.getInstance()?.userByUsernameAsync(email)
|
||||
}
|
||||
|
||||
if (dbUser.passwordEncryptionType !== PasswordEncryptionType.GRADIDO_ID) {
|
||||
@ -726,7 +726,15 @@ export class UserResolver {
|
||||
if (!humhubClient) {
|
||||
throw new LogError('cannot create humhub client')
|
||||
}
|
||||
return await humhubClient.createAutoLoginUrl(dbUser)
|
||||
const username = dbUser.alias ?? dbUser.gradidoID
|
||||
const humhubUser = await humhubClient.userByUsername(username)
|
||||
if (!humhubUser) {
|
||||
throw new LogError("user don't exist (any longer) on humhub")
|
||||
}
|
||||
if (humhubUser.account.status !== 1) {
|
||||
throw new LogError('user status is not 1', humhubUser.account.status)
|
||||
}
|
||||
return await humhubClient.createAutoLoginUrl(username)
|
||||
}
|
||||
|
||||
@Authorized([RIGHTS.SEARCH_ADMIN_USERS])
|
||||
|
||||
@ -28,7 +28,7 @@ export async function syncHumhub(
|
||||
return
|
||||
}
|
||||
logger.debug('retrieve user from humhub')
|
||||
const humhubUser = await humhubClient.userByEmail(user.emailContact.email)
|
||||
const humhubUser = await humhubClient.userByUsername(user.alias ?? user.gradidoID)
|
||||
const humhubUsers = new Map<string, GetUser>()
|
||||
if (humhubUser) {
|
||||
humhubUsers.set(user.emailContact.email, humhubUser)
|
||||
|
||||
@ -17,6 +17,9 @@ describe('Sidebar', () => {
|
||||
roles: [],
|
||||
},
|
||||
},
|
||||
$route: {
|
||||
path: '/',
|
||||
},
|
||||
}
|
||||
|
||||
const Wrapper = () => {
|
||||
@ -33,8 +36,8 @@ describe('Sidebar', () => {
|
||||
})
|
||||
|
||||
describe('the general section', () => {
|
||||
it('has eight nav-items', () => {
|
||||
expect(wrapper.findAll('ul').at(0).findAll('.nav-item')).toHaveLength(8)
|
||||
it('has seven nav-items', () => {
|
||||
expect(wrapper.findAll('ul').at(0).findAll('.nav-item')).toHaveLength(7)
|
||||
})
|
||||
|
||||
it('has nav-item "navigation.overview" in navbar', () => {
|
||||
@ -53,20 +56,16 @@ describe('Sidebar', () => {
|
||||
expect(wrapper.findAll('.nav-item').at(3).text()).toEqual('creation')
|
||||
})
|
||||
|
||||
it('has nav-item "GDT" in navbar', () => {
|
||||
expect(wrapper.findAll('.nav-item').at(4).text()).toContain('GDT')
|
||||
})
|
||||
|
||||
it('has nav-item "navigation.info" in navbar', () => {
|
||||
expect(wrapper.findAll('.nav-item').at(5).text()).toContain('navigation.info')
|
||||
expect(wrapper.findAll('.nav-item').at(4).text()).toContain('navigation.info')
|
||||
})
|
||||
|
||||
it('has nav-item "navigation.circles" in navbar', () => {
|
||||
expect(wrapper.findAll('.nav-item').at(6).text()).toContain('navigation.circles')
|
||||
expect(wrapper.findAll('.nav-item').at(5).text()).toContain('navigation.circles')
|
||||
})
|
||||
|
||||
it('has nav-item "navigation.usersearch" in navbar', () => {
|
||||
expect(wrapper.findAll('.nav-item').at(7).text()).toContain('navigation.usersearch')
|
||||
expect(wrapper.findAll('.nav-item').at(6).text()).toContain('navigation.usersearch')
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
@ -16,7 +16,7 @@
|
||||
<b-icon icon="cash" aria-hidden="true"></b-icon>
|
||||
<span class="ml-2">{{ $t('navigation.send') }}</span>
|
||||
</b-nav-item>
|
||||
<b-nav-item to="/transactions" class="mb-3" active-class="activeRoute">
|
||||
<b-nav-item to="/transactions" :class="transactionClass" active-class="activeRoute">
|
||||
<b-img src="/img/svg/transaction.svg" height="20" class="svg-icon" />
|
||||
<span class="ml-2">{{ $t('navigation.transactions') }}</span>
|
||||
</b-nav-item>
|
||||
@ -24,10 +24,6 @@
|
||||
<b-img src="/img/svg/community.svg" height="20" class="svg-icon" />
|
||||
<span class="ml-2">{{ $t('creation') }}</span>
|
||||
</b-nav-item>
|
||||
<b-nav-item to="/gdt" class="mb-3" active-class="activeRoute">
|
||||
<b-icon icon="layers" aria-hidden="true"></b-icon>
|
||||
<span class="ml-2">{{ $t('GDT') }}</span>
|
||||
</b-nav-item>
|
||||
<b-nav-item to="/information" class="mb-3" active-class="activeRoute">
|
||||
<b-img src="/img/svg/info.svg" height="20" class="svg-icon" />
|
||||
<span class="ml-2">{{ $t('navigation.info') }}</span>
|
||||
@ -86,6 +82,14 @@ export default {
|
||||
props: {
|
||||
shadow: { type: Boolean, required: false, default: true },
|
||||
},
|
||||
computed: {
|
||||
transactionClass() {
|
||||
if (this.$route.path === '/gdt') {
|
||||
return 'mb-3 activeRoute'
|
||||
}
|
||||
return 'mb-3'
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
|
||||
@ -59,8 +59,11 @@ export default {
|
||||
this.enableButton = true
|
||||
})
|
||||
.catch(() => {
|
||||
this.toastError('authenticateHumhubAutoLogin failed!')
|
||||
// this.toastError('authenticateHumhubAutoLogin failed!')
|
||||
this.enableButton = true
|
||||
// something went wrong with login link so we disable humhub
|
||||
this.$store.commit('humhubAllowed', false)
|
||||
this.$router.push('/settings/extern')
|
||||
})
|
||||
},
|
||||
},
|
||||
|
||||
@ -80,9 +80,9 @@
|
||||
</b-row>
|
||||
</b-tab>
|
||||
<div v-if="isCommunityService">
|
||||
<b-tab :title="$t('settings.community')">
|
||||
<b-tab class="community-service-tabs" :title="$t('settings.community')">
|
||||
<div class="h2">{{ $t('settings.allow-community-services') }}</div>
|
||||
<div v-if="isHumhub" class="">
|
||||
<div v-if="isHumhub" class="mt-3">
|
||||
<b-row>
|
||||
<b-col cols="12" md="6" lg="6">
|
||||
<div class="h3">{{ $t('Humhub.title') }}</div>
|
||||
@ -113,7 +113,7 @@
|
||||
</b-col>
|
||||
</b-row>
|
||||
</div>
|
||||
<div v-if="isGMS">
|
||||
<div v-if="isGMS" class="mt-3">
|
||||
<b-row>
|
||||
<b-col cols="12" md="6" lg="6">
|
||||
<div class="h3 text-muted">{{ $t('GMS.title') }}</div>
|
||||
@ -129,7 +129,7 @@
|
||||
/>
|
||||
</b-col>
|
||||
</b-row>
|
||||
<div class="h4 mt-3">{{ $t('GMS.desc') }}</div>
|
||||
<div class="h4 mt-3 text-muted">{{ $t('GMS.desc') }}</div>
|
||||
<div v-if="gmsAllowed">
|
||||
<b-row class="mb-4">
|
||||
<b-col cols="12" md="6" lg="6">
|
||||
@ -287,6 +287,9 @@ export default {
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.community-service-tabs {
|
||||
min-height: 315px;
|
||||
}
|
||||
.card-border-radius {
|
||||
border-radius: 0px 5px 5px 0px !important;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user