mirror of
https://github.com/IT4Change/gradido.git
synced 2026-03-01 12:44:43 +00:00
Merge branch 'master' into catch-verify-login
This commit is contained in:
commit
8660ed7350
2
.github/workflows/test.yml
vendored
2
.github/workflows/test.yml
vendored
@ -441,7 +441,7 @@ jobs:
|
||||
report_name: Coverage Admin Interface
|
||||
type: lcov
|
||||
result_path: ./coverage/lcov.info
|
||||
min_coverage: 50
|
||||
min_coverage: 53
|
||||
token: ${{ github.token }}
|
||||
|
||||
##############################################################################
|
||||
|
||||
16
README.md
16
README.md
@ -69,6 +69,22 @@ We are currently restructuring the service to reduce dependencies and unify busi
|
||||
|
||||
Once you have `docker-compose` up and running, you can open [http://localhost/vue](http://localhost/vue) and create yourself a new wallet account.
|
||||
|
||||
## How to release
|
||||
|
||||
A release is tagged on Github by its version number and published as github release. This is done automatically when a new version is defined in the [package.json](./package.json) and merged into master - furthermore we set all our sub-package-versions to the same version as the main package.json version to make version management as simple as possible.
|
||||
Each release is accompanied with release notes automatically generated from the git log which is available as [CHANGELOG.md](./CHANGELOG.md).
|
||||
|
||||
To generate the Changelog and set a new Version you should use the following commands in the main folder
|
||||
```bash
|
||||
git fetch --all
|
||||
yarn release
|
||||
```
|
||||
|
||||
The first command `git fetch --all` will make sure you have all tags previously defined which is required to generate a correct changelog. The second command `yarn release` will execute the changelog tool and set version numbers in the main package and sub-packages. It is required to do `yarn install` before you can use this command.
|
||||
After generating a new version you should commit the changes. This will be the CHANGELOG.md and several package.json files. This commit will be omitted in the changelog.
|
||||
|
||||
Note: The Changelog will be regenerated with all tags on release on the external builder tool, but will not be checked in there. The Changelog on the github release will therefore always be correct, on the repo it might be incorrect due to missing tags when executing the `yarn release` command.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
| Problem | Issue | Solution | Description |
|
||||
|
||||
7
admin/src/graphql/getCountPendingCreations.js
Normal file
7
admin/src/graphql/getCountPendingCreations.js
Normal file
@ -0,0 +1,7 @@
|
||||
import gql from 'graphql-tag'
|
||||
|
||||
export const countPendingCreations = gql`
|
||||
query {
|
||||
countPendingCreations
|
||||
}
|
||||
`
|
||||
16
admin/src/graphql/getPendingCreations.js
Normal file
16
admin/src/graphql/getPendingCreations.js
Normal file
@ -0,0 +1,16 @@
|
||||
import gql from 'graphql-tag'
|
||||
|
||||
export const getPendingCreations = gql`
|
||||
query {
|
||||
getPendingCreations {
|
||||
firstName
|
||||
lastName
|
||||
email
|
||||
amount
|
||||
memo
|
||||
date
|
||||
moderator
|
||||
creation
|
||||
}
|
||||
}
|
||||
`
|
||||
@ -5,6 +5,7 @@ export const verifyLogin = gql`
|
||||
verifyLogin {
|
||||
firstName
|
||||
lastName
|
||||
isAdmin
|
||||
id
|
||||
}
|
||||
}
|
||||
|
||||
@ -75,7 +75,7 @@ Vue.use(Toasted, {
|
||||
},
|
||||
})
|
||||
|
||||
addNavigationGuards(router, store)
|
||||
addNavigationGuards(router, store, apolloProvider.defaultClient)
|
||||
|
||||
new Vue({
|
||||
moment,
|
||||
|
||||
@ -4,11 +4,47 @@ import CreationConfirm from './CreationConfirm.vue'
|
||||
const localVue = global.localVue
|
||||
|
||||
const storeCommitMock = jest.fn()
|
||||
const toastedErrorMock = jest.fn()
|
||||
const apolloQueryMock = jest.fn().mockResolvedValue({
|
||||
data: {
|
||||
getPendingCreations: [
|
||||
{
|
||||
firstName: 'Bibi',
|
||||
lastName: 'Bloxberg',
|
||||
email: 'bibi@bloxberg.de',
|
||||
amount: 500,
|
||||
memo: 'Danke für alles',
|
||||
date: new Date(),
|
||||
moderator: 0,
|
||||
},
|
||||
{
|
||||
firstName: 'Räuber',
|
||||
lastName: 'Hotzenplotz',
|
||||
email: 'raeuber@hotzenplotz.de',
|
||||
amount: 1000000,
|
||||
memo: 'Gut Ergatert',
|
||||
date: new Date(),
|
||||
moderator: 0,
|
||||
},
|
||||
],
|
||||
},
|
||||
})
|
||||
|
||||
const mocks = {
|
||||
$store: {
|
||||
commit: storeCommitMock,
|
||||
},
|
||||
$apollo: {
|
||||
query: apolloQueryMock,
|
||||
},
|
||||
$toasted: {
|
||||
error: toastedErrorMock,
|
||||
},
|
||||
$moment: jest.fn((value) => {
|
||||
return {
|
||||
format: jest.fn((format) => value),
|
||||
}
|
||||
}),
|
||||
}
|
||||
|
||||
describe('CreationConfirm', () => {
|
||||
@ -32,9 +68,22 @@ describe('CreationConfirm', () => {
|
||||
it('commits resetOpenCreations to store', () => {
|
||||
expect(storeCommitMock).toBeCalledWith('resetOpenCreations')
|
||||
})
|
||||
it('commits setOpenCreations to store', () => {
|
||||
expect(storeCommitMock).toBeCalledWith('setOpenCreations', 2)
|
||||
})
|
||||
})
|
||||
|
||||
it('commits openCreationsPlus to store', () => {
|
||||
expect(storeCommitMock).toBeCalledWith('openCreationsPlus', 5)
|
||||
describe('server response is error', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks()
|
||||
apolloQueryMock.mockRejectedValue({
|
||||
message: 'Ouch!',
|
||||
})
|
||||
wrapper = Wrapper()
|
||||
})
|
||||
|
||||
it('toast an error message', () => {
|
||||
expect(toastedErrorMock).toBeCalledWith('Ouch!')
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
@ -1,9 +1,5 @@
|
||||
<template>
|
||||
<div class="creation-confirm">
|
||||
<small class="bg-danger text-light p-1">
|
||||
Die anzahl der offene Schöpfungen stimmen nicht! Diese wird bei absenden im $store
|
||||
hochgezählt. Die Liste die hier angezeigt wird ist SIMULIERT!
|
||||
</small>
|
||||
<user-table
|
||||
class="mt-4"
|
||||
type="PageCreationConfirm"
|
||||
@ -15,6 +11,7 @@
|
||||
</template>
|
||||
<script>
|
||||
import UserTable from '../components/UserTable.vue'
|
||||
import { getPendingCreations } from '../graphql/getPendingCreations'
|
||||
|
||||
export default {
|
||||
name: 'CreationConfirm',
|
||||
@ -30,98 +27,25 @@ export default {
|
||||
{ key: 'firstName', label: 'Vorname' },
|
||||
{ key: 'lastName', label: 'Nachname' },
|
||||
{
|
||||
key: 'creation_gdd',
|
||||
key: 'amount',
|
||||
label: 'Schöpfung',
|
||||
formatter: (value) => {
|
||||
return value + ' GDD'
|
||||
},
|
||||
},
|
||||
{ key: 'text', label: 'Text' },
|
||||
{ key: 'memo', label: 'Text' },
|
||||
{
|
||||
key: 'creation_date',
|
||||
key: 'date',
|
||||
label: 'Datum',
|
||||
formatter: (value) => {
|
||||
return value.long
|
||||
return this.$moment(value).format('ll')
|
||||
},
|
||||
},
|
||||
{ key: 'creation_moderator', label: 'Moderator' },
|
||||
{ key: 'moderator', label: 'Moderator' },
|
||||
{ key: 'edit_creation', label: 'ändern' },
|
||||
{ key: 'confirm', label: 'speichern' },
|
||||
],
|
||||
confirmResult: [
|
||||
{
|
||||
id: 1,
|
||||
email: 'dickerson@web.de',
|
||||
firstName: 'Dickerson',
|
||||
lastName: 'Macdonald',
|
||||
creation: '[450,200,700]',
|
||||
creation_gdd: '1000',
|
||||
text: 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam ',
|
||||
|
||||
creation_date: {
|
||||
short: 'November',
|
||||
long: '22/11/2021',
|
||||
},
|
||||
creation_moderator: 'Manuela Gast',
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
email: 'larsen@woob.de',
|
||||
firstName: 'Larsen',
|
||||
lastName: 'Shaw',
|
||||
creation: '[300,200,1000]',
|
||||
creation_gdd: '1000',
|
||||
text: 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam ',
|
||||
|
||||
creation_date: {
|
||||
short: 'November',
|
||||
long: '03/11/2021',
|
||||
},
|
||||
creation_moderator: 'Manuela Gast',
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
email: 'geneva@tete.de',
|
||||
firstName: 'Geneva',
|
||||
lastName: 'Wilson',
|
||||
creation: '[350,200,900]',
|
||||
creation_gdd: '1000',
|
||||
text: 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam',
|
||||
creation_date: {
|
||||
short: 'September',
|
||||
long: '27/09/2021',
|
||||
},
|
||||
creation_moderator: 'Manuela Gast',
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
email: 'viewrter@asdfvb.com',
|
||||
firstName: 'Soledare',
|
||||
lastName: 'Takker',
|
||||
creation: '[100,400,800]',
|
||||
creation_gdd: '500',
|
||||
text: 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo ',
|
||||
creation_date: {
|
||||
short: 'Oktober',
|
||||
long: '12/10/2021',
|
||||
},
|
||||
creation_moderator: 'Evelyn Roller',
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
email: 'dickerson@web.de',
|
||||
firstName: 'Dickerson',
|
||||
lastName: 'Macdonald',
|
||||
creation: '[100,400,800]',
|
||||
creation_gdd: '200',
|
||||
text: 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At',
|
||||
creation_date: {
|
||||
short: 'September',
|
||||
long: '05/09/2021',
|
||||
},
|
||||
creation_moderator: 'Manuela Gast',
|
||||
},
|
||||
],
|
||||
confirmResult: [],
|
||||
}
|
||||
},
|
||||
|
||||
@ -140,10 +64,23 @@ export default {
|
||||
this.$store.commit('openCreationsMinus', 1)
|
||||
}
|
||||
},
|
||||
getPendingCreations() {
|
||||
this.$apollo
|
||||
.query({
|
||||
query: getPendingCreations,
|
||||
})
|
||||
.then((result) => {
|
||||
this.$store.commit('resetOpenCreations')
|
||||
this.confirmResult = result.data.getPendingCreations.reverse()
|
||||
this.$store.commit('setOpenCreations', result.data.getPendingCreations.length)
|
||||
})
|
||||
.catch((error) => {
|
||||
this.$toasted.error(error.message)
|
||||
})
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.$store.commit('resetOpenCreations')
|
||||
this.$store.commit('openCreationsPlus', Object.keys(this.confirmResult).length)
|
||||
async created() {
|
||||
await this.getPendingCreations()
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
@ -76,7 +76,24 @@
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { getPendingCreations } from '../graphql/getPendingCreations'
|
||||
|
||||
export default {
|
||||
name: 'overview',
|
||||
methods: {
|
||||
getPendingCreations() {
|
||||
this.$apollo
|
||||
.query({
|
||||
query: getPendingCreations,
|
||||
})
|
||||
.then((result) => {
|
||||
this.$store.commit('setOpenCreations', result.data.getPendingCreations.length)
|
||||
})
|
||||
.catch()
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.getPendingCreations()
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
@ -1,12 +1,28 @@
|
||||
import { verifyLogin } from '../graphql/verifyLogin'
|
||||
import CONFIG from '../config'
|
||||
|
||||
const addNavigationGuards = (router, store) => {
|
||||
const addNavigationGuards = (router, store, apollo) => {
|
||||
// store token on `authenticate`
|
||||
router.beforeEach((to, from, next) => {
|
||||
router.beforeEach(async (to, from, next) => {
|
||||
if (to.path === '/authenticate' && to.query && to.query.token) {
|
||||
// TODO verify user to get user data
|
||||
store.commit('token', to.query.token)
|
||||
next({ path: '/' })
|
||||
await apollo
|
||||
.query({
|
||||
query: verifyLogin,
|
||||
fetchPolicy: 'network-only',
|
||||
})
|
||||
.then((result) => {
|
||||
const moderator = result.data.verifyLogin
|
||||
if (moderator.isAdmin) {
|
||||
store.commit('moderator', moderator)
|
||||
next({ path: '/' })
|
||||
} else {
|
||||
next({ path: '/not-found' })
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
next({ path: '/not-found' })
|
||||
})
|
||||
} else {
|
||||
next()
|
||||
}
|
||||
@ -16,7 +32,9 @@ const addNavigationGuards = (router, store) => {
|
||||
router.beforeEach((to, from, next) => {
|
||||
if (
|
||||
!CONFIG.DEBUG_DISABLE_AUTH && // we did not disabled the auth module for debug purposes
|
||||
!store.state.token && // we do not have a token
|
||||
(!store.state.token || // we do not have a token
|
||||
!store.state.moderator || // no moderator set in store
|
||||
!store.state.moderator.isAdmin) && // user is no admin
|
||||
to.path !== '/not-found' && // we are not on `not-found`
|
||||
to.path !== '/logout' // we are not on `logout`
|
||||
) {
|
||||
|
||||
@ -2,6 +2,13 @@ import addNavigationGuards from './guards'
|
||||
import router from './router'
|
||||
|
||||
const storeCommitMock = jest.fn()
|
||||
const apolloQueryMock = jest.fn().mockResolvedValue({
|
||||
data: {
|
||||
verifyLogin: {
|
||||
isAdmin: true,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
const store = {
|
||||
commit: storeCommitMock,
|
||||
@ -10,7 +17,11 @@ const store = {
|
||||
},
|
||||
}
|
||||
|
||||
addNavigationGuards(router, store)
|
||||
const apollo = {
|
||||
query: apolloQueryMock,
|
||||
}
|
||||
|
||||
addNavigationGuards(router, store, apollo)
|
||||
|
||||
describe('navigation guards', () => {
|
||||
beforeEach(() => {
|
||||
@ -21,18 +32,70 @@ describe('navigation guards', () => {
|
||||
const navGuard = router.beforeHooks[0]
|
||||
const next = jest.fn()
|
||||
|
||||
describe('with valid token', () => {
|
||||
it('commits the token to the store', async () => {
|
||||
describe('with valid token and as admin', () => {
|
||||
beforeEach(() => {
|
||||
navGuard({ path: '/authenticate', query: { token: 'valid-token' } }, {}, next)
|
||||
})
|
||||
|
||||
it('commits the token to the store', async () => {
|
||||
expect(storeCommitMock).toBeCalledWith('token', 'valid-token')
|
||||
})
|
||||
|
||||
it('commits the moderator to the store', () => {
|
||||
expect(storeCommitMock).toBeCalledWith('moderator', { isAdmin: true })
|
||||
})
|
||||
|
||||
it('redirects to /', async () => {
|
||||
navGuard({ path: '/authenticate', query: { token: 'valid-token' } }, {}, next)
|
||||
expect(next).toBeCalledWith({ path: '/' })
|
||||
})
|
||||
})
|
||||
|
||||
describe('with valid token and not as admin', () => {
|
||||
beforeEach(() => {
|
||||
apolloQueryMock.mockResolvedValue({
|
||||
data: {
|
||||
verifyLogin: {
|
||||
isAdmin: false,
|
||||
},
|
||||
},
|
||||
})
|
||||
navGuard({ path: '/authenticate', query: { token: 'valid-token' } }, {}, next)
|
||||
})
|
||||
|
||||
it('commits the token to the store', async () => {
|
||||
expect(storeCommitMock).toBeCalledWith('token', 'valid-token')
|
||||
})
|
||||
|
||||
it('does not commit the moderator to the store', () => {
|
||||
expect(storeCommitMock).not.toBeCalledWith('moderator', { isAdmin: false })
|
||||
})
|
||||
|
||||
it('redirects to /not-found', async () => {
|
||||
expect(next).toBeCalledWith({ path: '/not-found' })
|
||||
})
|
||||
})
|
||||
|
||||
describe('with valid token and server error on verification', () => {
|
||||
beforeEach(() => {
|
||||
apolloQueryMock.mockRejectedValue({
|
||||
message: 'Ouch!',
|
||||
})
|
||||
navGuard({ path: '/authenticate', query: { token: 'valid-token' } }, {}, next)
|
||||
})
|
||||
|
||||
it('commits the token to the store', async () => {
|
||||
expect(storeCommitMock).toBeCalledWith('token', 'valid-token')
|
||||
})
|
||||
|
||||
it('does not commit the moderator to the store', () => {
|
||||
expect(storeCommitMock).not.toBeCalledWith('moderator', { isAdmin: false })
|
||||
})
|
||||
|
||||
it('redirects to /not-found', async () => {
|
||||
expect(next).toBeCalledWith({ path: '/not-found' })
|
||||
})
|
||||
})
|
||||
|
||||
describe('without valid token', () => {
|
||||
it('does not commit the token to the store', async () => {
|
||||
navGuard({ path: '/authenticate' }, {}, next)
|
||||
@ -55,9 +118,16 @@ describe('navigation guards', () => {
|
||||
expect(next).toBeCalledWith({ path: '/not-found' })
|
||||
})
|
||||
|
||||
it('does not redirect when token in store', () => {
|
||||
it('redirects to not found with token in store and not moderator', () => {
|
||||
store.state.token = 'valid token'
|
||||
navGuard({ path: '/' }, {}, next)
|
||||
expect(next).toBeCalledWith({ path: '/not-found' })
|
||||
})
|
||||
|
||||
it('does not redirect with token in store and as moderator', () => {
|
||||
store.state.token = 'valid token'
|
||||
store.state.moderator = { isAdmin: true }
|
||||
navGuard({ path: '/' }, {}, next)
|
||||
expect(next).toBeCalledWith()
|
||||
})
|
||||
})
|
||||
|
||||
@ -18,6 +18,9 @@ export const mutations = {
|
||||
token: (state, token) => {
|
||||
state.token = token
|
||||
},
|
||||
setOpenCreations: (state, openCreations) => {
|
||||
state.openCreations = openCreations
|
||||
},
|
||||
moderator: (state, moderator) => {
|
||||
state.moderator = moderator
|
||||
},
|
||||
@ -26,6 +29,7 @@ export const mutations = {
|
||||
export const actions = {
|
||||
logout: ({ commit, state }) => {
|
||||
commit('token', null)
|
||||
commit('moderator', null)
|
||||
window.localStorage.clear()
|
||||
},
|
||||
}
|
||||
@ -38,7 +42,7 @@ const store = new Vuex.Store({
|
||||
],
|
||||
state: {
|
||||
token: CONFIG.DEBUG_DISABLE_AUTH ? 'validToken' : null,
|
||||
moderator: { name: 'Dertest Moderator', id: 0 },
|
||||
moderator: null,
|
||||
openCreations: 0,
|
||||
},
|
||||
// Syncronous mutation of the state
|
||||
|
||||
@ -1,11 +1,19 @@
|
||||
import store, { mutations, actions } from './store'
|
||||
import CONFIG from '../config'
|
||||
|
||||
const { token, openCreationsPlus, openCreationsMinus, resetOpenCreations } = mutations
|
||||
jest.mock('../config')
|
||||
|
||||
const {
|
||||
token,
|
||||
openCreationsPlus,
|
||||
openCreationsMinus,
|
||||
resetOpenCreations,
|
||||
setOpenCreations,
|
||||
moderator,
|
||||
} = mutations
|
||||
const { logout } = actions
|
||||
|
||||
const CONFIG = {
|
||||
DEBUG_DISABLE_AUTH: true,
|
||||
}
|
||||
CONFIG.DEBUG_DISABLE_AUTH = true
|
||||
|
||||
describe('Vuex store', () => {
|
||||
describe('mutations', () => {
|
||||
@ -40,6 +48,22 @@ describe('Vuex store', () => {
|
||||
expect(state.openCreations).toEqual(0)
|
||||
})
|
||||
})
|
||||
|
||||
describe('moderator', () => {
|
||||
it('sets the moderator object in state', () => {
|
||||
const state = { moderator: null }
|
||||
moderator(state, { id: 1 })
|
||||
expect(state.moderator).toEqual({ id: 1 })
|
||||
})
|
||||
})
|
||||
|
||||
describe('setOpenCreations', () => {
|
||||
it('sets the open creations to given value', () => {
|
||||
const state = { openCreations: 24 }
|
||||
setOpenCreations(state, 12)
|
||||
expect(state.openCreations).toEqual(12)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('actions', () => {
|
||||
@ -57,6 +81,11 @@ describe('Vuex store', () => {
|
||||
expect(commit).toBeCalledWith('token', null)
|
||||
})
|
||||
|
||||
it('deletes the moderator in store', () => {
|
||||
logout({ commit, state })
|
||||
expect(commit).toBeCalledWith('moderator', null)
|
||||
})
|
||||
|
||||
it.skip('clears the window local storage', () => {
|
||||
expect(windowStorageMock).toBeCalled()
|
||||
})
|
||||
|
||||
34
backend/src/graphql/model/PendingCreation.ts
Normal file
34
backend/src/graphql/model/PendingCreation.ts
Normal file
@ -0,0 +1,34 @@
|
||||
import { ObjectType, Field, Int } from 'type-graphql'
|
||||
|
||||
@ObjectType()
|
||||
export class PendingCreation {
|
||||
@Field(() => String)
|
||||
firstName: string
|
||||
|
||||
@Field(() => Int)
|
||||
id?: number
|
||||
|
||||
@Field(() => String)
|
||||
lastName: string
|
||||
|
||||
@Field(() => Number)
|
||||
userId: number
|
||||
|
||||
@Field(() => String)
|
||||
email: string
|
||||
|
||||
@Field(() => Date)
|
||||
date: Date
|
||||
|
||||
@Field(() => String)
|
||||
memo: string
|
||||
|
||||
@Field(() => Number)
|
||||
amount: BigInt
|
||||
|
||||
@Field(() => Number)
|
||||
moderator: number
|
||||
|
||||
@Field(() => [Number])
|
||||
creation: number[]
|
||||
}
|
||||
@ -1,7 +1,7 @@
|
||||
import { Resolver, Query, Arg, Args, Authorized, Mutation } from 'type-graphql'
|
||||
import { getCustomRepository, Raw } from 'typeorm'
|
||||
import { UserAdmin } from '../model/UserAdmin'
|
||||
import { LoginUserRepository } from '../../typeorm/repository/LoginUser'
|
||||
import { PendingCreation } from '../model/PendingCreation'
|
||||
import { RIGHTS } from '../../auth/RIGHTS'
|
||||
import { TransactionCreationRepository } from '../../typeorm/repository/TransactionCreation'
|
||||
import { PendingCreationRepository } from '../../typeorm/repository/PendingCreation'
|
||||
@ -14,19 +14,19 @@ export class AdminResolver {
|
||||
@Authorized([RIGHTS.SEARCH_USERS])
|
||||
@Query(() => [UserAdmin])
|
||||
async searchUsers(@Arg('searchText') searchText: string): Promise<UserAdmin[]> {
|
||||
const loginUserRepository = getCustomRepository(LoginUserRepository)
|
||||
const loginUsers = await loginUserRepository.findBySearchCriteria(searchText)
|
||||
const users = await Promise.all(
|
||||
loginUsers.map(async (loginUser) => {
|
||||
const user = new UserAdmin()
|
||||
user.firstName = loginUser.firstName
|
||||
user.lastName = loginUser.lastName
|
||||
user.email = loginUser.email
|
||||
user.creation = await getUserCreations(loginUser.id)
|
||||
return user
|
||||
const userRepository = getCustomRepository(UserRepository)
|
||||
const users = await userRepository.findBySearchCriteria(searchText)
|
||||
const adminUsers = await Promise.all(
|
||||
users.map(async (user) => {
|
||||
const adminUser = new UserAdmin()
|
||||
adminUser.firstName = user.firstName
|
||||
adminUser.lastName = user.lastName
|
||||
adminUser.email = user.email
|
||||
adminUser.creation = await getUserCreations(user.id)
|
||||
return adminUser
|
||||
}),
|
||||
)
|
||||
return users
|
||||
return adminUsers
|
||||
}
|
||||
|
||||
@Mutation(() => [Number])
|
||||
@ -52,6 +52,30 @@ export class AdminResolver {
|
||||
}
|
||||
return await getUserCreations(user.id)
|
||||
}
|
||||
|
||||
@Query(() => [PendingCreation])
|
||||
async getPendingCreations(): Promise<PendingCreation[]> {
|
||||
const pendingCreationRepository = getCustomRepository(PendingCreationRepository)
|
||||
const pendingCreations = await pendingCreationRepository.find()
|
||||
|
||||
const pendingCreationsPromise = await Promise.all(
|
||||
pendingCreations.map(async (pendingCreation) => {
|
||||
const userRepository = getCustomRepository(UserRepository)
|
||||
const user = await userRepository.findOneOrFail({ id: pendingCreation.userId })
|
||||
|
||||
const newPendingCreation = {
|
||||
...pendingCreation,
|
||||
firstName: user.firstName,
|
||||
lastName: user.lastName,
|
||||
email: user.email,
|
||||
creation: await getUserCreations(user.id),
|
||||
}
|
||||
|
||||
return newPendingCreation
|
||||
}),
|
||||
)
|
||||
return pendingCreationsPromise
|
||||
}
|
||||
}
|
||||
|
||||
async function getUserCreations(id: number): Promise<number[]> {
|
||||
|
||||
@ -30,4 +30,17 @@ export class UserRepository extends Repository<User> {
|
||||
})
|
||||
return usersIndiced
|
||||
}
|
||||
|
||||
async findBySearchCriteria(searchCriteria: string): Promise<User[]> {
|
||||
return await this.createQueryBuilder('user')
|
||||
.where(
|
||||
'user.firstName like :name or user.lastName like :lastName or user.email like :email',
|
||||
{
|
||||
name: `%${searchCriteria}%`,
|
||||
lastName: `%${searchCriteria}%`,
|
||||
email: `%${searchCriteria}%`,
|
||||
},
|
||||
)
|
||||
.getMany()
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
|
||||
/*
|
||||
Elopage Webhook
|
||||
|
||||
|
||||
@ -6,6 +6,7 @@ PROJECT_DIR="${SCRIPT_DIR}/../"
|
||||
FRONTEND_DIR="${PROJECT_DIR}/frontend/"
|
||||
BACKEND_DIR="${PROJECT_DIR}/backend/"
|
||||
DATABASE_DIR="${PROJECT_DIR}/database/"
|
||||
ADMIN_DIR="${PROJECT_DIR}/admin/"
|
||||
|
||||
# navigate to project directory
|
||||
cd ${PROJECT_DIR}
|
||||
@ -23,6 +24,8 @@ cd ${BACKEND_DIR}
|
||||
yarn version --no-git-tag-version --no-commit-hooks --no-commit --new-version ${VERSION}
|
||||
cd ${DATABASE_DIR}
|
||||
yarn version --no-git-tag-version --no-commit-hooks --no-commit --new-version ${VERSION}
|
||||
cd ${ADMIN_DIR}
|
||||
yarn version --no-git-tag-version --no-commit-hooks --no-commit --new-version ${VERSION}
|
||||
|
||||
# generate changelog
|
||||
cd ${PROJECT_DIR}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user