Merge branch 'master' into eslint-dht-import

This commit is contained in:
Ulf Gebhardt 2023-06-16 14:40:50 +02:00 committed by GitHub
commit 81139cb1d7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 164 additions and 100 deletions

View File

@ -12,7 +12,7 @@ Decimal.set({
})
const constants = {
DB_VERSION: '0066-x-community-sendcoins-transactions_table',
DB_VERSION: '0067-private_key_in_community_table',
DECAY_START_TIME: new Date('2021-05-13 17:46:31-0000'), // GMT+0
LOG4JS_CONFIG: 'log4js-config.json',
// default log level on production should be info

View File

@ -1,12 +1,9 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
import { ObjectType, Field } from 'type-graphql'
@ObjectType()
export class KlickTipp {
constructor(json: any) {
this.newsletterState = json.status === 'Subscribed'
constructor(newsletterState: boolean) {
this.newsletterState = newsletterState
}
@Field(() => Boolean)

View File

@ -8,17 +8,7 @@ import { TransactionLink as DbTransactionLink } from '@entity/TransactionLink'
import { User as DbUser } from '@entity/User'
import { UserContact as DbUserContact } from '@entity/UserContact'
import i18n from 'i18n'
import {
Resolver,
Query,
Args,
Arg,
Authorized,
Ctx,
UseMiddleware,
Mutation,
Int,
} from 'type-graphql'
import { Resolver, Query, Args, Arg, Authorized, Ctx, Mutation, Int } from 'type-graphql'
import { v4 as uuidv4 } from 'uuid'
import { CreateUserArgs } from '@arg/CreateUserArgs'
@ -60,7 +50,6 @@ import {
EVENT_ADMIN_USER_DELETE,
EVENT_ADMIN_USER_UNDELETE,
} from '@/event/Events'
import { klicktippNewsletterStateMiddleware } from '@/middleware/klicktippMiddleware'
import { isValidPassword } from '@/password/EncryptorUtils'
import { encryptPassword, verifyPassword } from '@/password/PasswordEncryptor'
import { Context, getUser, getClientTimezoneOffset } from '@/server/context'
@ -76,6 +65,7 @@ import { randombytes_random } from 'sodium-native'
import { FULL_CREATION_AVAILABLE } from './const/const'
import { getUserCreations } from './util/creations'
import { findUserByIdentifier } from './util/findUserByIdentifier'
import { getKlicktippState } from './util/getKlicktippState'
import { validateAlias } from './util/validateAlias'
const LANGUAGES = ['de', 'en', 'es', 'fr', 'nl']
@ -120,7 +110,6 @@ const newGradidoID = async (): Promise<string> => {
export class UserResolver {
@Authorized([RIGHTS.VERIFY_LOGIN])
@Query(() => User)
@UseMiddleware(klicktippNewsletterStateMiddleware)
async verifyLogin(@Ctx() context: Context): Promise<User> {
logger.info('verifyLogin...')
// TODO refactor and do not have duplicate code with login(see below)
@ -130,12 +119,12 @@ export class UserResolver {
user.hasElopage = await this.hasElopage(context)
logger.debug(`verifyLogin... successful: ${user.firstName}.${user.lastName}`)
user.klickTipp = await getKlicktippState(userEntity.emailContact.email)
return user
}
@Authorized([RIGHTS.LOGIN])
@Mutation(() => User)
@UseMiddleware(klicktippNewsletterStateMiddleware)
async login(
@Args() { email, password, publisherId }: UnsecureLoginArgs,
@Ctx() context: Context,
@ -181,6 +170,7 @@ export class UserResolver {
dbUser.publisherId = publisherId
await DbUser.save(dbUser)
}
user.klickTipp = await getKlicktippState(dbUser.emailContact.email)
context.setHeaders.push({
key: 'token',

View File

@ -0,0 +1,19 @@
/* eslint-disable @typescript-eslint/no-unsafe-return */
import { KlickTipp } from '@model/KlickTipp'
import { getKlickTippUser } from '@/apis/KlicktippController'
import { klickTippLogger as logger } from '@/server/logger'
export const getKlicktippState = async (email: string): Promise<KlickTipp> => {
try {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const klickTippUser = await getKlickTippUser(email)
if (klickTippUser) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
return new KlickTipp(klickTippUser.status === 'Subscribed')
}
} catch (err) {
logger.error('There is no klicktipp user for email', email, err)
}
return new KlickTipp(false)
}

View File

@ -1,31 +0,0 @@
/* eslint-disable @typescript-eslint/no-unsafe-return */
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
/* eslint-disable @typescript-eslint/restrict-template-expressions */
/* eslint-disable @typescript-eslint/no-unsafe-argument */
import { MiddlewareFn } from 'type-graphql'
import { KlickTipp } from '@model/KlickTipp'
import { getKlickTippUser } from '@/apis/KlicktippController'
import { klickTippLogger as logger } from '@/server/logger'
export const klicktippNewsletterStateMiddleware: MiddlewareFn = async (
/* eslint-disable-next-line @typescript-eslint/no-unused-vars */
{ root, args, context, info },
next,
) => {
// eslint-disable-next-line n/callback-return
const result = await next()
let klickTipp = new KlickTipp({ status: 'Unsubscribed' })
try {
const klickTippUser = await getKlickTippUser(result.email)
if (klickTippUser) {
klickTipp = new KlickTipp(klickTippUser)
}
} catch (err) {
logger.error(`There is no user for (email='${result.email}') ${err}`)
}
result.klickTipp = klickTipp
return result
}

View File

@ -0,0 +1,63 @@
import {
BaseEntity,
Entity,
PrimaryGeneratedColumn,
Column,
CreateDateColumn,
UpdateDateColumn,
} from 'typeorm'
@Entity('communities')
export class Community extends BaseEntity {
@PrimaryGeneratedColumn('increment', { unsigned: true })
id: number
@Column({ name: 'foreign', type: 'bool', nullable: false, default: true })
foreign: boolean
@Column({ name: 'url', length: 255, nullable: false })
url: string
@Column({ name: 'public_key', type: 'binary', length: 64, nullable: false })
publicKey: Buffer
@Column({ name: 'private_key', type: 'binary', length: 64, nullable: true })
privateKey: Buffer | null
@Column({
name: 'community_uuid',
type: 'char',
length: 36,
nullable: true,
collation: 'utf8mb4_unicode_ci',
})
communityUuid: string | null
@Column({ name: 'authenticated_at', type: 'datetime', nullable: true })
authenticatedAt: Date | null
@Column({ name: 'name', type: 'varchar', length: 40, nullable: true })
name: string | null
@Column({ name: 'description', type: 'varchar', length: 255, nullable: true })
description: string | null
@CreateDateColumn({ name: 'creation_date', type: 'datetime', nullable: true })
creationDate: Date | null
@CreateDateColumn({
name: 'created_at',
type: 'datetime',
default: () => 'CURRENT_TIMESTAMP(3)',
nullable: false,
})
createdAt: Date
@UpdateDateColumn({
name: 'updated_at',
type: 'datetime',
onUpdate: 'CURRENT_TIMESTAMP(3)',
nullable: true,
})
updatedAt: Date | null
}

View File

@ -1 +1 @@
export { Community } from './0065-refactor_communities_table/Community'
export { Community } from './0067-private_key_in_community_table/Community'

View File

@ -0,0 +1,17 @@
/* MIGRATION TO ADD PRIVATE KEY IN COMMUNITY TABLE
*
* This migration adds a field for the private key in the community.table
*/
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
/* eslint-disable @typescript-eslint/no-explicit-any */
export async function upgrade(queryFn: (query: string, values?: any[]) => Promise<Array<any>>) {
await queryFn(
'ALTER TABLE `communities` ADD COLUMN `private_key` binary(64) DEFAULT NULL AFTER `public_key`;',
)
}
export async function downgrade(queryFn: (query: string, values?: any[]) => Promise<Array<any>>) {
await queryFn('ALTER TABLE `communities` DROP COLUMN `private_key`;')
}

View File

@ -1,3 +1,4 @@
node_modules
**/*.min.js
build
build
coverage

View File

@ -13,7 +13,7 @@ module.exports = {
'plugin:import/recommended',
'plugin:import/typescript',
// 'plugin:security/recommended',
// 'plugin:@eslint-community/eslint-comments/recommended',
'plugin:@eslint-community/eslint-comments/recommended',
],
settings: {
'import/parsers': {
@ -101,44 +101,44 @@ module.exports = {
],
'import/prefer-default-export': 'off',
// n
// 'n/handle-callback-err': 'error',
// 'n/no-callback-literal': 'error',
// 'n/no-exports-assign': 'error',
// 'n/no-extraneous-import': 'error',
// 'n/no-extraneous-require': 'error',
// 'n/no-hide-core-modules': 'error',
// 'n/no-missing-import': 'off', // not compatible with typescript
// 'n/no-missing-require': 'error',
// 'n/no-new-require': 'error',
// 'n/no-path-concat': 'error',
// 'n/no-process-exit': 'error',
// 'n/no-unpublished-bin': 'error',
// 'n/no-unpublished-import': 'off', // TODO need to exclude seeds
// 'n/no-unpublished-require': 'error',
// 'n/no-unsupported-features': ['error', { ignores: ['modules'] }],
// 'n/no-unsupported-features/es-builtins': 'error',
// 'n/no-unsupported-features/es-syntax': 'error',
// 'n/no-unsupported-features/node-builtins': 'error',
// 'n/process-exit-as-throw': 'error',
// 'n/shebang': 'error',
// 'n/callback-return': 'error',
// 'n/exports-style': 'error',
// 'n/file-extension-in-import': 'off',
// 'n/global-require': 'error',
// 'n/no-mixed-requires': 'error',
// 'n/no-process-env': 'error',
// 'n/no-restricted-import': 'error',
// 'n/no-restricted-require': 'error',
// 'n/no-sync': 'error',
// 'n/prefer-global/buffer': 'error',
// 'n/prefer-global/console': 'error',
// 'n/prefer-global/process': 'error',
// 'n/prefer-global/text-decoder': 'error',
// 'n/prefer-global/text-encoder': 'error',
// 'n/prefer-global/url': 'error',
// 'n/prefer-global/url-search-params': 'error',
// 'n/prefer-promises/dns': 'error',
// 'n/prefer-promises/fs': 'error',
'n/handle-callback-err': 'error',
'n/no-callback-literal': 'error',
'n/no-exports-assign': 'error',
'n/no-extraneous-import': 'error',
'n/no-extraneous-require': 'error',
'n/no-hide-core-modules': 'error',
'n/no-missing-import': 'off', // not compatible with typescript
'n/no-missing-require': 'error',
'n/no-new-require': 'error',
'n/no-path-concat': 'error',
'n/no-process-exit': 'error',
'n/no-unpublished-bin': 'error',
'n/no-unpublished-import': 'off', // TODO need to exclude seeds
'n/no-unpublished-require': 'error',
'n/no-unsupported-features': ['error', { ignores: ['modules'] }],
'n/no-unsupported-features/es-builtins': 'error',
'n/no-unsupported-features/es-syntax': 'error',
'n/no-unsupported-features/node-builtins': 'error',
'n/process-exit-as-throw': 'error',
'n/shebang': 'error',
'n/callback-return': 'error',
'n/exports-style': 'error',
'n/file-extension-in-import': 'off',
'n/global-require': 'error',
'n/no-mixed-requires': 'error',
'n/no-process-env': 'error',
'n/no-restricted-import': 'error',
'n/no-restricted-require': 'error',
'n/no-sync': 'error',
'n/prefer-global/buffer': 'error',
'n/prefer-global/console': 'error',
'n/prefer-global/process': 'error',
'n/prefer-global/text-decoder': 'error',
'n/prefer-global/text-encoder': 'error',
'n/prefer-global/url': 'error',
'n/prefer-global/url-search-params': 'error',
'n/prefer-promises/dns': 'error',
'n/prefer-promises/fs': 'error',
// promise
// 'promise/catch-or-return': 'error',
// 'promise/no-return-wrap': 'error',
@ -155,10 +155,10 @@ module.exports = {
// 'promise/prefer-await-to-callbacks': 'error',
// 'promise/no-multiple-resolved': 'error',
// eslint comments
// '@eslint-community/eslint-comments/disable-enable-pair': ['error', { allowWholeFile: true }],
// '@eslint-community/eslint-comments/no-restricted-disable': 'error',
// '@eslint-community/eslint-comments/no-use': 'off',
// '@eslint-community/eslint-comments/require-description': 'off',
'@eslint-community/eslint-comments/disable-enable-pair': ['error', { allowWholeFile: true }],
'@eslint-community/eslint-comments/no-restricted-disable': 'error',
'@eslint-community/eslint-comments/no-use': 'off',
'@eslint-community/eslint-comments/require-description': 'off',
},
overrides: [
// only for ts files

View File

@ -17,10 +17,12 @@ module.exports = {
'@/(.*)': '<rootDir>/src/$1',
'@test/(.*)': '<rootDir>/test/$1',
'@entity/(.*)':
// eslint-disable-next-line n/no-process-env
process.env.NODE_ENV === 'development'
? '<rootDir>/../database/entity/$1'
: '<rootDir>/../database/build/entity/$1',
'@dbTools/(.*)':
// eslint-disable-next-line n/no-process-env
process.env.NODE_ENV === 'development'
? '<rootDir>/../database/src/$1'
: '<rootDir>/../database/build/src/$1',

View File

@ -48,5 +48,8 @@
"prettier": "^2.8.7",
"jest": "^27.2.4",
"ts-jest": "^27.0.5"
},
"engines": {
"node": ">=14"
}
}

View File

@ -1,10 +1,10 @@
// ATTENTION: DO NOT PUT ANY SECRETS IN HERE (or the .env)
/* eslint-disable n/no-process-env */
import dotenv from 'dotenv'
dotenv.config()
const constants = {
DB_VERSION: '0066-x-community-sendcoins-transactions_table',
DB_VERSION: '0067-private_key_in_community_table',
LOG4JS_CONFIG: 'log4js-config.json',
// default log level on production should be info
LOG_LEVEL: process.env.LOG_LEVEL || 'info',

View File

@ -222,6 +222,7 @@ async function writeHomeCommunityEntry(keyPair: KeyPair): Promise<void> {
if (homeCom) {
// simply update the existing entry, but it MUST keep the ID and UUID because of possible relations
homeCom.publicKey = keyPair.publicKey
homeCom.privateKey = keyPair.secretKey
homeCom.url = CONFIG.FEDERATION_COMMUNITY_URL + '/api/'
homeCom.name = CONFIG.COMMUNITY_NAME
homeCom.description = CONFIG.COMMUNITY_DESCRIPTION
@ -232,6 +233,7 @@ async function writeHomeCommunityEntry(keyPair: KeyPair): Promise<void> {
homeCom = new DbCommunity()
homeCom.foreign = false
homeCom.publicKey = keyPair.publicKey
homeCom.privateKey = keyPair.secretKey
homeCom.communityUuid = await newCommunityUuid()
homeCom.url = CONFIG.FEDERATION_COMMUNITY_URL + '/api/'
homeCom.name = CONFIG.COMMUNITY_NAME

View File

@ -32,5 +32,5 @@ async function main() {
main().catch((e) => {
// eslint-disable-next-line no-console
console.error(e)
process.exit(1)
throw e
})

View File

@ -11,7 +11,7 @@ Decimal.set({
*/
const constants = {
DB_VERSION: '0066-x-community-sendcoins-transactions_table',
DB_VERSION: '0067-private_key_in_community_table',
// DECAY_START_TIME: new Date('2021-05-13 17:46:31-0000'), // GMT+0
LOG4JS_CONFIG: 'log4js-config.json',
// default log level on production should be info

View File

@ -86,6 +86,7 @@ export default {
const loader = this.$loading.show({
container: this.$refs.submitButton,
})
this.$root.$bvToast.hide()
this.$apollo
.mutate({
mutation: login,