mirror of
https://github.com/IT4Change/gradido.git
synced 2025-12-13 07:45:54 +00:00
Merge branch 'master' into paginate-user-table
This commit is contained in:
commit
2e25c280cf
4
.gitignore
vendored
4
.gitignore
vendored
@ -8,4 +8,6 @@ package-lock.json
|
||||
/deployment/bare_metal/.env
|
||||
/deployment/bare_metal/nginx/sites-available/gradido.conf
|
||||
/deployment/bare_metal/nginx/sites-available/update-page.conf
|
||||
/deployment/bare_metal/nginx/update-page/updating.html
|
||||
/deployment/bare_metal/nginx/update-page/updating.html
|
||||
/deployment/bare_metal/log
|
||||
/deployment/bare_metal/backup
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
GRAPHQL_URI=http://localhost:4000/graphql
|
||||
WALLET_AUTH_URL=http://localhost/authenticate?token=$1
|
||||
WALLET_AUTH_URL=http://localhost/authenticate?token={token}
|
||||
WALLET_URL=http://localhost/login
|
||||
DEBUG_DISABLE_AUTH=false
|
||||
4
admin/.env.template
Normal file
4
admin/.env.template
Normal file
@ -0,0 +1,4 @@
|
||||
GRAPHQL_URI=$GRAPHQL_URI
|
||||
WALLET_AUTH_URL=$WALLET_AUTH_URL
|
||||
WALLET_URL=$WALLET_URL
|
||||
DEBUG_DISABLE_AUTH=false
|
||||
@ -38,7 +38,7 @@ export default {
|
||||
this.$store.dispatch('logout')
|
||||
},
|
||||
wallet() {
|
||||
window.location = CONFIG.WALLET_AUTH_URL.replace('$1', this.$store.state.token)
|
||||
window.location = CONFIG.WALLET_AUTH_URL.replace('{token}', this.$store.state.token)
|
||||
this.$store.dispatch('logout') // logout without redirect
|
||||
},
|
||||
},
|
||||
|
||||
@ -19,7 +19,7 @@ const environment = {
|
||||
|
||||
const endpoints = {
|
||||
GRAPHQL_URI: process.env.GRAPHQL_URI || 'http://localhost:4000/graphql',
|
||||
WALLET_AUTH_URL: process.env.WALLET_AUTH_URL || 'http://localhost/authenticate?token=$1',
|
||||
WALLET_AUTH_URL: process.env.WALLET_AUTH_URL || 'http://localhost/authenticate?token={token}',
|
||||
WALLET_URL: process.env.WALLET_URL || 'http://localhost/login',
|
||||
}
|
||||
|
||||
|
||||
@ -2,7 +2,6 @@ import { ApolloClient, ApolloLink, InMemoryCache, HttpLink } from 'apollo-boost'
|
||||
import VueApollo from 'vue-apollo'
|
||||
import CONFIG from '../config'
|
||||
import store from '../store/store'
|
||||
import router from '../router/router'
|
||||
import i18n from '../i18n'
|
||||
|
||||
const httpLink = new HttpLink({ uri: CONFIG.GRAPHQL_URI })
|
||||
@ -18,7 +17,7 @@ const authLink = new ApolloLink((operation, forward) => {
|
||||
if (response.errors && response.errors[0].message === '403.13 - Client certificate revoked') {
|
||||
response.errors[0].message = i18n.t('error.session-expired')
|
||||
store.dispatch('logout', null)
|
||||
if (router.currentRoute.path !== '/logout') router.push('/logout')
|
||||
window.location.assign(CONFIG.WALLET_URL)
|
||||
return response
|
||||
}
|
||||
const newToken = operation.getContext().response.headers.get('token')
|
||||
|
||||
@ -4,12 +4,10 @@ import CONFIG from '../config'
|
||||
|
||||
import VueApollo from 'vue-apollo'
|
||||
import store from '../store/store'
|
||||
import router from '../router/router'
|
||||
import i18n from '../i18n'
|
||||
|
||||
jest.mock('vue-apollo')
|
||||
jest.mock('../store/store')
|
||||
jest.mock('../router/router')
|
||||
jest.mock('../i18n')
|
||||
|
||||
jest.mock('apollo-boost', () => {
|
||||
@ -59,13 +57,11 @@ describe('apolloProvider', () => {
|
||||
errors: [{ message: '403.13 - Client certificate revoked' }],
|
||||
}
|
||||
|
||||
// mock router
|
||||
const routerPushMock = jest.fn()
|
||||
router.push = routerPushMock
|
||||
router.currentRoute = {
|
||||
path: '/overview',
|
||||
const windowLocationMock = jest.fn()
|
||||
delete window.location
|
||||
window.location = {
|
||||
assign: windowLocationMock,
|
||||
}
|
||||
|
||||
// mock context
|
||||
const setContextMock = jest.fn()
|
||||
const getContextMock = jest.fn(() => {
|
||||
@ -128,21 +124,8 @@ describe('apolloProvider', () => {
|
||||
expect(storeDispatchMock).toBeCalledWith('logout', null)
|
||||
})
|
||||
|
||||
describe('current route is not logout', () => {
|
||||
it('redirects to logout', () => {
|
||||
expect(routerPushMock).toBeCalledWith('/logout')
|
||||
})
|
||||
})
|
||||
|
||||
describe('current route is logout', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks()
|
||||
router.currentRoute.path = '/logout'
|
||||
})
|
||||
|
||||
it('does not redirect to logout', () => {
|
||||
expect(routerPushMock).not.toBeCalled()
|
||||
})
|
||||
it('redirects to logout', () => {
|
||||
expect(windowLocationMock).toBeCalledWith('http://localhost/login')
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
@ -19,7 +19,8 @@ DB_DATABASE=gradido_community
|
||||
#RESEND_TIME=
|
||||
RESEND_TIME=10
|
||||
|
||||
#EMAIL_LINK_VERIFICATION=http://localhost/checkEmail/$1
|
||||
#EMAIL_LINK_VERIFICATION=http://localhost/checkEmail/{code}
|
||||
#EMAIL_LINK_SETPASSWORD=http://localhost/reset/{code}
|
||||
|
||||
#KLICKTIPP_USER=
|
||||
#KLICKTIPP_PASSWORD=
|
||||
|
||||
34
backend/.env.template
Normal file
34
backend/.env.template
Normal file
@ -0,0 +1,34 @@
|
||||
PORT=4000
|
||||
JWT_SECRET=$JWT_SECRET
|
||||
JWT_EXPIRES_IN=10m
|
||||
GRAPHIQL=false
|
||||
GDT_API_URL=https://gdt.gradido.net
|
||||
DB_HOST=localhost
|
||||
DB_PORT=3306
|
||||
DB_USER=$DB_USER
|
||||
DB_PASSWORD=$DB_PASSWORD
|
||||
DB_DATABASE=gradido_community
|
||||
|
||||
EMAIL=$EMAIL
|
||||
EMAIL_USERNAME=$EMAIL_USERNAME
|
||||
EMAIL_SENDER=$EMAIL_SENDER
|
||||
EMAIL_PASSWORD=$EMAIL_PASSWORD
|
||||
EMAIL_SMTP_URL=$EMAIL_SMTP_URL
|
||||
EMAIL_SMTP_PORT=587
|
||||
#RESEND_TIME=1 minute, 60 => 1hour, 1440 (60 minutes * 24 hours) => 24 hours
|
||||
RESEND_TIME=10
|
||||
|
||||
EMAIL_LINK_VERIFICATION=$EMAIL_LINK_VERIFICATION
|
||||
EMAIL_LINK_SETPASSWORD=$EMAIL_LINK_SETPASSWORD
|
||||
|
||||
#KLICKTIPP_USER=
|
||||
#KLICKTIPP_PASSWORD=
|
||||
#KLICKTIPP_APIKEY_DE=
|
||||
#KLICKTIPP_APIKEY_EN=
|
||||
#KLICKTIPP=true
|
||||
COMMUNITY_NAME=
|
||||
COMMUNITY_URL=
|
||||
COMMUNITY_REGISTER_URL=
|
||||
COMMUNITY_DESCRIPTION=
|
||||
|
||||
WEBHOOK_ELOPAGE_SECRET=$WEBHOOK_ELOPAGE_SECRET
|
||||
@ -18,6 +18,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/jest": "^27.0.2",
|
||||
"apollo-log": "^1.1.0",
|
||||
"apollo-server-express": "^2.25.2",
|
||||
"apollo-server-testing": "^2.25.2",
|
||||
"axios": "^0.21.1",
|
||||
|
||||
@ -18,6 +18,8 @@ const database = {
|
||||
DB_USER: process.env.DB_USER || 'root',
|
||||
DB_PASSWORD: process.env.DB_PASSWORD || '',
|
||||
DB_DATABASE: process.env.DB_DATABASE || 'gradido_community',
|
||||
TYPEORM_LOGGING_RELATIVE_PATH:
|
||||
process.env.TYPEORM_LOGGING_RELATIVE_PATH || '../deployment/bare_metal/log/typeorm.backend.log',
|
||||
}
|
||||
|
||||
const klicktipp = {
|
||||
@ -50,8 +52,9 @@ const email = {
|
||||
EMAIL_PASSWORD: process.env.EMAIL_PASSWORD || 'xxx',
|
||||
EMAIL_SMTP_URL: process.env.EMAIL_SMTP_URL || 'gmail.com',
|
||||
EMAIL_SMTP_PORT: process.env.EMAIL_SMTP_PORT || '587',
|
||||
EMAIL_LINK_VERIFICATION: process.env.EMAIL_LINK_VERIFICATION || 'http://localhost/checkEmail/$1',
|
||||
EMAIL_LINK_SETPASSWORD: process.env.EMAIL_LINK_SETPASSWORD || 'http://localhost/reset/$1',
|
||||
EMAIL_LINK_VERIFICATION:
|
||||
process.env.EMAIL_LINK_VERIFICATION || 'http://localhost/checkEmail/{code}',
|
||||
EMAIL_LINK_SETPASSWORD: process.env.EMAIL_LINK_SETPASSWORD || 'http://localhost/reset/{code}',
|
||||
RESEND_TIME: isNaN(resendTime) ? 10 : resendTime,
|
||||
}
|
||||
|
||||
|
||||
@ -170,7 +170,7 @@ describe('UserResolver', () => {
|
||||
|
||||
describe('account activation email', () => {
|
||||
it('sends an account activation email', () => {
|
||||
const activationLink = CONFIG.EMAIL_LINK_VERIFICATION.replace(/\$1/g, emailOptIn)
|
||||
const activationLink = CONFIG.EMAIL_LINK_VERIFICATION.replace(/{code}/g, emailOptIn)
|
||||
expect(sendAccountActivationEmail).toBeCalledWith({
|
||||
link: activationLink,
|
||||
firstName: 'Peter',
|
||||
|
||||
@ -448,7 +448,7 @@ export class UserResolver {
|
||||
const emailOptIn = await createEmailOptIn(loginUserId, queryRunner)
|
||||
|
||||
const activationLink = CONFIG.EMAIL_LINK_VERIFICATION.replace(
|
||||
/\$1/g,
|
||||
/{code}/g,
|
||||
emailOptIn.verificationCode.toString(),
|
||||
)
|
||||
const emailSent = await sendAccountActivationEmail({
|
||||
@ -486,7 +486,7 @@ export class UserResolver {
|
||||
const emailOptIn = await createEmailOptIn(loginUser.id, queryRunner)
|
||||
|
||||
const activationLink = CONFIG.EMAIL_LINK_VERIFICATION.replace(
|
||||
/\$1/g,
|
||||
/{code}/g,
|
||||
emailOptIn.verificationCode.toString(),
|
||||
)
|
||||
|
||||
@ -523,7 +523,7 @@ export class UserResolver {
|
||||
const optInCode = await getOptInCode(loginUser)
|
||||
|
||||
const link = CONFIG.EMAIL_LINK_SETPASSWORD.replace(
|
||||
/\$1/g,
|
||||
/{code}/g,
|
||||
optInCode.verificationCode.toString(),
|
||||
)
|
||||
|
||||
|
||||
@ -74,6 +74,7 @@ const createServer = async (context: any = serverContext): Promise<any> => {
|
||||
const apollo = new ApolloServer({
|
||||
schema: await schema(),
|
||||
playground: CONFIG.GRAPHIQL,
|
||||
introspection: CONFIG.GRAPHIQL,
|
||||
context,
|
||||
plugins,
|
||||
})
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
|
||||
|
||||
import { ApolloLogPlugin } from 'apollo-log'
|
||||
|
||||
const plugins = [
|
||||
{
|
||||
requestDidStart() {
|
||||
@ -19,6 +21,7 @@ const plugins = [
|
||||
}
|
||||
},
|
||||
},
|
||||
ApolloLogPlugin(),
|
||||
]
|
||||
|
||||
export default plugins
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createConnection, Connection } from 'typeorm'
|
||||
import { createConnection, Connection, FileLogger } from 'typeorm'
|
||||
import CONFIG from '../config'
|
||||
import { entities } from '@entity/index'
|
||||
|
||||
@ -15,6 +15,10 @@ const connection = async (): Promise<Connection | null> => {
|
||||
database: CONFIG.DB_DATABASE,
|
||||
entities,
|
||||
synchronize: false,
|
||||
logging: true,
|
||||
logger: new FileLogger('all', {
|
||||
logPath: CONFIG.TYPEORM_LOGGING_RELATIVE_PATH,
|
||||
}),
|
||||
})
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
|
||||
@ -35,7 +35,7 @@ import { LoginUserRepository } from '../typeorm/repository/LoginUser'
|
||||
|
||||
export const elopageWebhook = async (req: any, res: any): Promise<void> => {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('Elopage Hook received')
|
||||
console.log('Elopage Hook received', req.body)
|
||||
res.status(200).end() // Responding is important
|
||||
const loginElopgaeBuyRepository = await getCustomRepository(LoginElopageBuysRepository)
|
||||
const loginElopgaeBuy = new LoginElopageBuys()
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@apollo/protobufjs@1.2.2":
|
||||
"@apollo/protobufjs@1.2.2", "@apollo/protobufjs@^1.0.3":
|
||||
version "1.2.2"
|
||||
resolved "https://registry.yarnpkg.com/@apollo/protobufjs/-/protobufjs-1.2.2.tgz#4bd92cd7701ccaef6d517cdb75af2755f049f87c"
|
||||
integrity sha512-vF+zxhPiLtkwxONs6YanSt1EpwpGilThpneExUN5K3tCymuxNnVq2yojTvnpRjv2QfsEIt/n7ozPIIzBLwGIDQ==
|
||||
@ -1273,6 +1273,24 @@ apollo-link@^1.2.14:
|
||||
tslib "^1.9.3"
|
||||
zen-observable-ts "^0.8.21"
|
||||
|
||||
apollo-log@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/apollo-log/-/apollo-log-1.1.0.tgz#e21287c917cf735b77adc06f07034f965e9b24de"
|
||||
integrity sha512-TciLu+85LSqk7t7ZGKrYN5jFiCcRMLujBjrLiOQGHGgVVkvmKlwK0oELSS9kiHQIhTq23p8qVVWb08spLpQ7Jw==
|
||||
dependencies:
|
||||
apollo-server-plugin-base "^0.10.4"
|
||||
chalk "^4.1.0"
|
||||
fast-safe-stringify "^2.0.7"
|
||||
loglevelnext "^4.0.1"
|
||||
nanoid "^3.1.20"
|
||||
|
||||
apollo-reporting-protobuf@^0.6.2:
|
||||
version "0.6.2"
|
||||
resolved "https://registry.yarnpkg.com/apollo-reporting-protobuf/-/apollo-reporting-protobuf-0.6.2.tgz#5572866be9b77f133916532b10e15fbaa4158304"
|
||||
integrity sha512-WJTJxLM+MRHNUxt1RTl4zD0HrLdH44F2mDzMweBj1yHL0kSt8I1WwoiF/wiGVSpnG48LZrBegCaOJeuVbJTbtw==
|
||||
dependencies:
|
||||
"@apollo/protobufjs" "^1.0.3"
|
||||
|
||||
apollo-reporting-protobuf@^0.8.0:
|
||||
version "0.8.0"
|
||||
resolved "https://registry.yarnpkg.com/apollo-reporting-protobuf/-/apollo-reporting-protobuf-0.8.0.tgz#ae9d967934d3d8ed816fc85a0d8068ef45c371b9"
|
||||
@ -1280,6 +1298,13 @@ apollo-reporting-protobuf@^0.8.0:
|
||||
dependencies:
|
||||
"@apollo/protobufjs" "1.2.2"
|
||||
|
||||
apollo-server-caching@^0.5.3:
|
||||
version "0.5.3"
|
||||
resolved "https://registry.yarnpkg.com/apollo-server-caching/-/apollo-server-caching-0.5.3.tgz#cf42a77ad09a46290a246810075eaa029b5305e1"
|
||||
integrity sha512-iMi3087iphDAI0U2iSBE9qtx9kQoMMEWr6w+LwXruBD95ek9DWyj7OeC2U/ngLjRsXM43DoBDXlu7R+uMjahrQ==
|
||||
dependencies:
|
||||
lru-cache "^6.0.0"
|
||||
|
||||
apollo-server-caching@^0.7.0:
|
||||
version "0.7.0"
|
||||
resolved "https://registry.yarnpkg.com/apollo-server-caching/-/apollo-server-caching-0.7.0.tgz#e6d1e68e3bb571cba63a61f60b434fb771c6ff39"
|
||||
@ -1318,7 +1343,7 @@ apollo-server-core@^2.25.2:
|
||||
subscriptions-transport-ws "^0.9.19"
|
||||
uuid "^8.0.0"
|
||||
|
||||
apollo-server-env@^3.1.0:
|
||||
apollo-server-env@^3.0.0, apollo-server-env@^3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/apollo-server-env/-/apollo-server-env-3.1.0.tgz#0733c2ef50aea596cc90cf40a53f6ea2ad402cd0"
|
||||
integrity sha512-iGdZgEOAuVop3vb0F2J3+kaBVi4caMoxefHosxmgzAbbSpvWehB8Y1QiSyyMeouYC38XNVk5wnZl+jdGSsWsIQ==
|
||||
@ -1354,6 +1379,13 @@ apollo-server-express@^2.25.2:
|
||||
subscriptions-transport-ws "^0.9.19"
|
||||
type-is "^1.6.16"
|
||||
|
||||
apollo-server-plugin-base@^0.10.4:
|
||||
version "0.10.4"
|
||||
resolved "https://registry.yarnpkg.com/apollo-server-plugin-base/-/apollo-server-plugin-base-0.10.4.tgz#fbf73f64f95537ca9f9639dd7c535eb5eeb95dcd"
|
||||
integrity sha512-HRhbyHgHFTLP0ImubQObYhSgpmVH4Rk1BinnceZmwudIVLKrqayIVOELdyext/QnSmmzg5W7vF3NLGBcVGMqDg==
|
||||
dependencies:
|
||||
apollo-server-types "^0.6.3"
|
||||
|
||||
apollo-server-plugin-base@^0.13.0:
|
||||
version "0.13.0"
|
||||
resolved "https://registry.yarnpkg.com/apollo-server-plugin-base/-/apollo-server-plugin-base-0.13.0.tgz#3f85751a420d3c4625355b6cb3fbdd2acbe71f13"
|
||||
@ -1368,6 +1400,15 @@ apollo-server-testing@^2.25.2:
|
||||
dependencies:
|
||||
apollo-server-core "^2.25.2"
|
||||
|
||||
apollo-server-types@^0.6.3:
|
||||
version "0.6.3"
|
||||
resolved "https://registry.yarnpkg.com/apollo-server-types/-/apollo-server-types-0.6.3.tgz#f7aa25ff7157863264d01a77d7934aa6e13399e8"
|
||||
integrity sha512-aVR7SlSGGY41E1f11YYz5bvwA89uGmkVUtzMiklDhZ7IgRJhysT5Dflt5IuwDxp+NdQkIhVCErUXakopocFLAg==
|
||||
dependencies:
|
||||
apollo-reporting-protobuf "^0.6.2"
|
||||
apollo-server-caching "^0.5.3"
|
||||
apollo-server-env "^3.0.0"
|
||||
|
||||
apollo-server-types@^0.9.0:
|
||||
version "0.9.0"
|
||||
resolved "https://registry.yarnpkg.com/apollo-server-types/-/apollo-server-types-0.9.0.tgz#ccf550b33b07c48c72f104fbe2876232b404848b"
|
||||
@ -2559,6 +2600,11 @@ fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6:
|
||||
resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
|
||||
integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=
|
||||
|
||||
fast-safe-stringify@^2.0.7:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz#c406a83b6e70d9e35ce3b30a81141df30aeba884"
|
||||
integrity sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==
|
||||
|
||||
fastq@^1.6.0:
|
||||
version "1.13.0"
|
||||
resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c"
|
||||
@ -4008,6 +4054,11 @@ loglevel@^1.6.7:
|
||||
resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.7.1.tgz#005fde2f5e6e47068f935ff28573e125ef72f197"
|
||||
integrity sha512-Hesni4s5UkWkwCGJMQGAh71PaLUmKFM60dHvq0zi/vDhhrzuk+4GgNbTXJ12YYQJn6ZKBDNIjYcuQGKudvqrIw==
|
||||
|
||||
loglevelnext@^4.0.1:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/loglevelnext/-/loglevelnext-4.0.1.tgz#4406c6348c243a35272ac75d7d8e4e60ecbcd011"
|
||||
integrity sha512-/tlMUn5wqgzg9msy0PiWc+8fpVXEuYPq49c2RGyw2NAh0hSrgq6j/Z3YPnwWsILMoFJ+ZT6ePHnWUonkjDnq2Q==
|
||||
|
||||
long@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28"
|
||||
@ -4194,6 +4245,11 @@ named-placeholders@^1.1.2:
|
||||
dependencies:
|
||||
lru-cache "^4.1.3"
|
||||
|
||||
nanoid@^3.1.20:
|
||||
version "3.1.32"
|
||||
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.32.tgz#8f96069e6239cc0a9ae8c0d3b41a3b4933a88c0a"
|
||||
integrity sha512-F8mf7R3iT9bvThBoW4tGXhXFHCctyCiUUPrWF8WaTqa3h96d9QybkSeba43XVOOE3oiLfkVDe4bT8MeGmkrTxw==
|
||||
|
||||
natural-compare@^1.4.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
|
||||
|
||||
8
database/.env.template
Normal file
8
database/.env.template
Normal file
@ -0,0 +1,8 @@
|
||||
DB_HOST=localhost
|
||||
DB_PORT=3306
|
||||
DB_USER=$DB_USER
|
||||
DB_PASSWORD=$DB_PASSWORD
|
||||
DB_DATABASE=gradido_community
|
||||
MIGRATIONS_TABLE=migrations
|
||||
|
||||
TYPEORM_SEEDING_FACTORIES=src/factories/**/*{.ts,.js}
|
||||
@ -1,14 +1,37 @@
|
||||
NGINX_SERVER_NAME=_
|
||||
GRADIDO_LOG_PATH=/home/gradido/gradido/deployment/bare_metal/log
|
||||
|
||||
#Example data
|
||||
# start script
|
||||
DEPLOY_SEED_DATA=false
|
||||
|
||||
#DEPLOY_SEED_DATA=true
|
||||
#
|
||||
#NGINX_REWRITE_LEGACY_URLS=true
|
||||
#NGINX_SSL=true
|
||||
#NGINX_SERVER_NAME=stage1.gradido.net
|
||||
#NGINX_SSL_CERTIFICATE=/etc/letsencrypt/live/stage1.gradido.net/fullchain.pem
|
||||
#NGINX_SSL_CERTIFICATE_KEY=/etc/letsencrypt/live/stage1.gradido.net/privkey.pem
|
||||
#NGINX_SSL_DHPARAM=/etc/letsencrypt/ssl-dhparams.pem
|
||||
#NGINX_SSL_INCLUDE=/etc/letsencrypt/options-ssl-nginx.conf
|
||||
#NGINX_UPDATE_PAGE_ROOT=/home/gradido/gradido/deployment/bare_metal/nginx/update-page
|
||||
# nginx
|
||||
NGINX_REWRITE_LEGACY_URLS=true
|
||||
NGINX_SSL=true
|
||||
NGINX_SERVER_NAME=stage1.gradido.net
|
||||
NGINX_SSL_CERTIFICATE=/etc/letsencrypt/live/stage1.gradido.net/fullchain.pem
|
||||
NGINX_SSL_CERTIFICATE_KEY=/etc/letsencrypt/live/stage1.gradido.net/privkey.pem
|
||||
NGINX_SSL_DHPARAM=/etc/letsencrypt/ssl-dhparams.pem
|
||||
NGINX_SSL_INCLUDE=/etc/letsencrypt/options-ssl-nginx.conf
|
||||
NGINX_UPDATE_PAGE_ROOT=/home/gradido/gradido/deployment/bare_metal/nginx/update-page
|
||||
|
||||
# webhook
|
||||
WEBHOOK_GITHUB_SECRET=secret
|
||||
WEBHOOK_GITHUB_BRANCH=master
|
||||
|
||||
# backend
|
||||
EMAIL=true
|
||||
EMAIL_USERNAME=peter@lustig.de
|
||||
EMAIL_SENDER=peter@lustig.de
|
||||
EMAIL_PASSWORD=1234
|
||||
EMAIL_SMTP_URL=smtp.lustig.de
|
||||
EMAIL_LINK_VERIFICATION=https://stage1.gradido.net/checkEmail/{code}
|
||||
EMAIL_LINK_SETPASSWORD=https://stage1.gradido.net/reset/{code}
|
||||
|
||||
WEBHOOK_ELOPAGE_SECRET=secret
|
||||
|
||||
# frontend
|
||||
GRAPHQL_URI=https://stage1.gradido.net/graphql
|
||||
ADMIN_AUTH_URL=https://stage1.gradido.net/admin/authenticate?token={token}
|
||||
|
||||
# admin
|
||||
WALLET_AUTH_URL=https://stage1.gradido.net/authenticate?token={token}
|
||||
WALLET_URL=https://stage1.gradido.net/login
|
||||
28
deployment/bare_metal/backup.sh
Executable file
28
deployment/bare_metal/backup.sh
Executable file
@ -0,0 +1,28 @@
|
||||
#!/bin/bash
|
||||
|
||||
# This script will shut down all services, backup the whole database and restart the services
|
||||
|
||||
# Find current directory & configure paths
|
||||
set -o allexport
|
||||
SCRIPT_PATH=$(realpath $0)
|
||||
SCRIPT_DIR=$(dirname $SCRIPT_PATH)
|
||||
PROJECT_ROOT=$SCRIPT_DIR/../..
|
||||
set +o allexport
|
||||
|
||||
# Load backend .env for DB_USERNAME, DB_PASSWORD & DB_DATABASE
|
||||
# NOTE: all config values will be in process.env when starting
|
||||
# the services and will therefore take precedence over the .env
|
||||
if [ -f "$PROJECT_ROOT/backend/.env" ]; then
|
||||
export $(cat $PROJECT_ROOT/backend/.env | sed 's/#.*//g' | xargs)
|
||||
else
|
||||
export $(cat $PROJECT_ROOT/backend/.env.dist | sed 's/#.*//g' | xargs)
|
||||
fi
|
||||
|
||||
# Stop Services
|
||||
pm2 stop gradido-backend
|
||||
|
||||
# Backup data
|
||||
mysqldump --databases --single-transaction --quick --lock-tables=false > ${SCRIPT_DIR}/backup/mariadb-backup-$(date +%d-%m-%Y_%H-%M-%S).sql -u ${DB_USER} -p${DB_PASSWORD} ${DB_DATABASE}
|
||||
|
||||
# Start Services
|
||||
pm2 start gradido-backend
|
||||
0
deployment/bare_metal/backup/.gitkeep
Normal file
0
deployment/bare_metal/backup/.gitkeep
Normal file
@ -3,15 +3,25 @@
|
||||
# This install script requires the minimum requirements already installed.
|
||||
# How to do this is described in detail in [setup.md](./setup.md)
|
||||
|
||||
# Load .env or .env.dist if not present
|
||||
# Find current directory & configure paths
|
||||
set -o allexport
|
||||
if [ -f ".env" ]; then
|
||||
source .env
|
||||
else
|
||||
source .env.dist
|
||||
fi
|
||||
SCRIPT_PATH=$(realpath $0)
|
||||
SCRIPT_DIR=$(dirname $SCRIPT_PATH)
|
||||
PROJECT_ROOT=$SCRIPT_DIR/../..
|
||||
set +o allexport
|
||||
|
||||
# Load .env or .env.dist if not present
|
||||
# NOTE: all config values will be in process.env when starting
|
||||
# the services and will therefore take precedence over the .env
|
||||
if [ -f "$SCRIPT_DIR/.env" ]; then
|
||||
export $(cat $SCRIPT_DIR/.env | sed 's/#.*//g' | xargs)
|
||||
else
|
||||
export $(cat $SCRIPT_DIR/.env.dist | sed 's/#.*//g' | xargs)
|
||||
fi
|
||||
|
||||
# Configure git
|
||||
git config pull.ff only
|
||||
|
||||
# Install mariadb
|
||||
sudo apt-get install -y mariadb-server
|
||||
sudo mysql_secure_installation
|
||||
@ -23,57 +33,26 @@ sudo mysql_secure_installation
|
||||
# Remove test database and access to it? [Y/n] Y
|
||||
# Reload privilege tables now? [Y/n] Y
|
||||
|
||||
# create db user
|
||||
DB_USER=gradido
|
||||
DB_PASSWORD=$(< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c${1:-32};echo);
|
||||
# create table
|
||||
#create database gradido_community
|
||||
# DEFAULT CHARACTER SET utf8mb4
|
||||
# DEFAULT COLLATE utf8mb4_unicode_ci;
|
||||
# GRANT ALL PRIVILEGES ON gradido_community.* TO '$DB_USER'@'localhost';
|
||||
sudo mysql <<EOFMYSQL
|
||||
CREATE USER '$DB_USER'@'localhost' IDENTIFIED BY '$DB_PASSWD';
|
||||
GRANT ALL PRIVILEGES ON *.* TO '$DB_USER'@'localhost';
|
||||
FLUSH PRIVILEGES;
|
||||
EOFMYSQL
|
||||
# TODO generate .env
|
||||
echo $DB_PASSWORD
|
||||
|
||||
#TODO go to database
|
||||
#TODO generate this
|
||||
#TODO database setup
|
||||
cp .env.dist .env
|
||||
|
||||
#TODO go to backend
|
||||
#TODO generate this
|
||||
#TODO database setup
|
||||
#TODOchange jwt secret
|
||||
#TODO change email releated stuff
|
||||
cp .env.dist .env
|
||||
|
||||
#TODO go to frontend
|
||||
#TODO generate this
|
||||
#TODO backend url
|
||||
#TODO admin url
|
||||
cp .env.dist .env
|
||||
|
||||
#TODO go to admin
|
||||
#TODO generate this
|
||||
#TODO change graphqlurl
|
||||
#TODO change wallet url
|
||||
|
||||
cp .env.dist .env
|
||||
|
||||
#TODO import old database
|
||||
|
||||
# Install nginx
|
||||
sudo apt-get install -y nginx
|
||||
sudo rm /etc/nginx/sites-enabled/default
|
||||
sudo ln -s /home/gradido/gradido/deployment/bare_metal/nginx/sites-available/gradido.conf /etc/nginx/sites-available
|
||||
sudo ln -s /etc/nginx/sites-available/gradido.conf /etc/nginx/sites-enabled
|
||||
# sudo ln -s /etc/nginx/sites-available/gradido.conf /etc/nginx/sites-enabled
|
||||
sudo ln -s /home/gradido/gradido/deployment/bare_metal/nginx/sites-available/update-page.conf /etc/nginx/sites-available
|
||||
cd /etc/nginx
|
||||
sudo ln -s /home/gradido/gradido/deployment/bare_metal/nginx/common common
|
||||
sudo ln -s /home/gradido/gradido/deployment/bare_metal/nginx/common /etc/nginx/
|
||||
sudo rmdir /etc/nginx/conf.d
|
||||
sudo ln -s /home/gradido/gradido/deployment/bare_metal/nginx/conf.d /etc/nginx/
|
||||
|
||||
# Allow nginx configuration and restart for gradido
|
||||
#TODO generate file
|
||||
sudo nano /etc/sudoers.d/gradido
|
||||
> gradido ALL=(ALL) NOPASSWD: /etc/init.d/nginx start,/etc/init.d/nginx stop,/etc/init.d/nginx restart
|
||||
sudo chmod a+rw /etc/nginx/sites-enabled
|
||||
|
||||
# Install node 16.x
|
||||
curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash -
|
||||
sudo apt-get install -y nodejs
|
||||
sudo apt-get install -y build-essential
|
||||
|
||||
# Install yarn
|
||||
sudo apt-get install -y curl
|
||||
@ -83,73 +62,64 @@ echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/source
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y yarn
|
||||
|
||||
# Install node 16.x
|
||||
curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash -
|
||||
sudo apt-get install -y nodejs
|
||||
sudo apt-get install -y build-essential
|
||||
|
||||
# Install pm2
|
||||
sudo yarn global add pm2
|
||||
pm2 startup
|
||||
> execute command output in shell
|
||||
|
||||
# Install certbot
|
||||
sudo apt-get install -y certbot
|
||||
sudo apt-get install -y python3-certbot-nginx
|
||||
sudo certbot --certonly
|
||||
sudo certbot
|
||||
> Enter email address (used for urgent renewal and security notices) > support@gradido.net
|
||||
> Please read the Terms of Service at > Y
|
||||
> Would you be willing, once your first certificate is successfully issued, to > N
|
||||
> No names were found in your configuration files. Please enter in your domain > stage1.gradido.net
|
||||
|
||||
git config pull.ff only
|
||||
# Install logrotate
|
||||
# sudo apt-get install -y logrotate
|
||||
envsubst "$(env | sed -e 's/=.*//' -e 's/^/\$/g')" < $SCRIPT_DIR/logrotate/gradido.conf.template > $SCRIPT_DIR/logrotate/gradido.conf
|
||||
sudo mv $SCRIPT_DIR/logrotate/gradido.conf /etc/logrotate.d/gradido.conf
|
||||
sudo chown root:root /etc/logrotate.d/gradido.conf
|
||||
|
||||
# Allow nginx configuration and restart for gradido
|
||||
sudo nano /etc/sudoers.d/gradido
|
||||
> gradido ALL=(ALL) NOPASSWD: /etc/init.d/nginx start,/etc/init.d/nginx stop,/etc/init.d/nginx restart
|
||||
sudo chmod a+rw /etc/nginx/sites-enabled
|
||||
# Install mysql autobackup
|
||||
sudo apt-get install -y automysqlbackup
|
||||
|
||||
# Webhooks (optional)
|
||||
sudo apt install webhook
|
||||
nano ~/hooks.json
|
||||
```
|
||||
[
|
||||
{
|
||||
"id": "github",
|
||||
"execute-command": "/home/gradido/gradido/deployment/bare_metal/start.sh",
|
||||
"pass-arguments-to-command": [
|
||||
{
|
||||
"source": "string",
|
||||
"name": "new_deployment"
|
||||
},
|
||||
],
|
||||
"command-working-directory": "/home/gradido/gradido/deployment/bare_metal",
|
||||
"trigger-rule": {
|
||||
"and": [
|
||||
{
|
||||
"match": {
|
||||
"type": "payload-hash-sha1",
|
||||
"secret": "secret",
|
||||
"parameter": {
|
||||
"source": "header",
|
||||
"name": "X-Hub-Signature"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"match": {
|
||||
"type": "value",
|
||||
"value": "refs/heads/new_deployment",
|
||||
"parameter": {
|
||||
"source": "payload",
|
||||
"name": "ref"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
```
|
||||
# Webhooks (optional) (for development)
|
||||
sudo apt install -y webhook
|
||||
# TODO generate
|
||||
# put hook into github
|
||||
# TODO adjust secret
|
||||
# TODO adjust branch if needed
|
||||
# https://stage1.gradido.net/hooks/github
|
||||
envsubst "$(env | sed -e 's/=.*//' -e 's/^/\$/g')" < $SCRIPT_DIR/webhook/hooks.json.template > ~/hooks.json
|
||||
|
||||
webhook -hooks ~/hooks.json &
|
||||
# or for debugging
|
||||
webhook -hooks ~/hooks.json -verbose
|
||||
# webhook -hooks ~/hooks.json -verbose
|
||||
|
||||
# create db user
|
||||
export DB_USER=gradido
|
||||
export DB_PASSWORD=$(< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c${1:-32};echo);
|
||||
sudo mysql <<EOFMYSQL
|
||||
CREATE USER '$DB_USER'@'localhost' IDENTIFIED BY '$DB_PASSWORD';
|
||||
GRANT ALL PRIVILEGES ON *.* TO '$DB_USER'@'localhost';
|
||||
FLUSH PRIVILEGES;
|
||||
EOFMYSQL
|
||||
|
||||
# Configure database
|
||||
envsubst "$(env | sed -e 's/=.*//' -e 's/^/\$/g')" < $PROJECT_ROOT/database/.env.template > $PROJECT_ROOT/database/.env
|
||||
|
||||
# Configure backend
|
||||
export JWT_SECRET=$(< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c${1:-32};echo);
|
||||
envsubst "$(env | sed -e 's/=.*//' -e 's/^/\$/g')" < $PROJECT_ROOT/backend/.env.template > $PROJECT_ROOT/backend/.env
|
||||
|
||||
# Configure frontend
|
||||
envsubst "$(env | sed -e 's/=.*//' -e 's/^/\$/g')" < $PROJECT_ROOT/frontend/.env.template > $PROJECT_ROOT/frontend/.env
|
||||
|
||||
# Configure admin
|
||||
envsubst "$(env | sed -e 's/=.*//' -e 's/^/\$/g')" < $PROJECT_ROOT/admin/.env.template > $PROJECT_ROOT/admin/.env
|
||||
|
||||
# Start gradido
|
||||
# Note: on first startup some errors will occur - nothing serious
|
||||
./start.sh
|
||||
0
deployment/bare_metal/log/.gitkeep
Normal file
0
deployment/bare_metal/log/.gitkeep
Normal file
7
deployment/bare_metal/logrotate/gradido.conf.template
Normal file
7
deployment/bare_metal/logrotate/gradido.conf.template
Normal file
@ -0,0 +1,7 @@
|
||||
$GRADIDO_LOG_PATH/* {
|
||||
weekly
|
||||
rotate 26
|
||||
size 10M
|
||||
compress
|
||||
delaycompress
|
||||
}
|
||||
4
deployment/bare_metal/nginx/conf.d/logging.conf
Normal file
4
deployment/bare_metal/nginx/conf.d/logging.conf
Normal file
@ -0,0 +1,4 @@
|
||||
log_format gradido_log '$remote_addr - $remote_user [$time_local] '
|
||||
'"$request_method $status $request_uri"'
|
||||
' "$http_referer" "$http_user_agent"'
|
||||
' $server_protocol $body_bytes_sent $request_time';
|
||||
@ -21,9 +21,18 @@ server {
|
||||
|
||||
include /etc/nginx/common/protect.conf;
|
||||
include /etc/nginx/common/protect_add_header.conf;
|
||||
#include /etc/nginx/common/ssl.conf;
|
||||
|
||||
#gzip_static on;
|
||||
gzip on;
|
||||
gzip_proxied any;
|
||||
gzip_types
|
||||
text/css
|
||||
text/javascript
|
||||
text/xml
|
||||
text/plain
|
||||
application/javascript
|
||||
application/x-javascript
|
||||
application/json;
|
||||
|
||||
# Legacy URLS
|
||||
set $REWRITE_LEGACY_URLS "$NGINX_REWRITE_LEGACY_URLS";
|
||||
@ -42,6 +51,9 @@ server {
|
||||
|
||||
proxy_pass http://127.0.0.1:3000;
|
||||
proxy_redirect off;
|
||||
|
||||
access_log $GRADIDO_LOG_PATH/nginx-access.frontend.log gradido_log;
|
||||
error_log $GRADIDO_LOG_PATH/nginx-error.frontend.log warn;
|
||||
}
|
||||
|
||||
# Backend
|
||||
@ -55,6 +67,9 @@ server {
|
||||
|
||||
proxy_pass http://127.0.0.1:4000;
|
||||
proxy_redirect off;
|
||||
|
||||
access_log $GRADIDO_LOG_PATH/nginx-access.backend.log gradido_log;
|
||||
error_log $GRADIDO_LOG_PATH/nginx-error.backend.log warn;
|
||||
}
|
||||
|
||||
# Backend webhooks
|
||||
@ -68,11 +83,17 @@ server {
|
||||
|
||||
proxy_pass http://127.0.0.1:4000/hook;
|
||||
proxy_redirect off;
|
||||
|
||||
access_log $GRADIDO_LOG_PATH/nginx-access.backend.hook.log gradido_log;
|
||||
error_log $GRADIDO_LOG_PATH/nginx-error.backend.hook.log warn;
|
||||
}
|
||||
|
||||
# Webhook reverse proxy
|
||||
location /hooks/ {
|
||||
proxy_pass http://127.0.0.1:9000/hooks/;
|
||||
|
||||
access_log $GRADIDO_LOG_PATH/nginx-access.hooks.log gradido_log;
|
||||
error_log $GRADIDO_LOG_PATH/nginx-error.hooks.log warn;
|
||||
}
|
||||
|
||||
# Admin Frontend
|
||||
@ -86,6 +107,9 @@ server {
|
||||
|
||||
proxy_pass http://127.0.0.1:8080/;
|
||||
proxy_redirect off;
|
||||
|
||||
access_log $GRADIDO_LOG_PATH/nginx-access.admin.log gradido_log;
|
||||
error_log $GRADIDO_LOG_PATH/nginx-error.admin.log warn;
|
||||
}
|
||||
|
||||
# TODO this could be a performance optimization
|
||||
@ -98,6 +122,4 @@ server {
|
||||
# }
|
||||
# try_files $uri $uri/ /index.html = 404;
|
||||
#}
|
||||
|
||||
#access_log /var/log/nginx/access.log main;
|
||||
}
|
||||
@ -6,9 +6,18 @@ server {
|
||||
|
||||
include /etc/nginx/common/protect.conf;
|
||||
include /etc/nginx/common/protect_add_header.conf;
|
||||
#include /etc/nginx/common/ssl.conf;
|
||||
|
||||
#gzip_static on;
|
||||
gzip on;
|
||||
gzip_proxied any;
|
||||
gzip_types
|
||||
text/css
|
||||
text/javascript
|
||||
text/xml
|
||||
text/plain
|
||||
application/javascript
|
||||
application/x-javascript
|
||||
application/json;
|
||||
|
||||
# Legacy URLS
|
||||
set $REWRITE_LEGACY_URLS "$NGINX_REWRITE_LEGACY_URLS";
|
||||
@ -27,6 +36,9 @@ server {
|
||||
|
||||
proxy_pass http://127.0.0.1:3000;
|
||||
proxy_redirect off;
|
||||
|
||||
access_log $GRADIDO_LOG_PATH/nginx-access.frontend.log gradido_log;
|
||||
error_log $GRADIDO_LOG_PATH/nginx-error.frontend.log warn;
|
||||
}
|
||||
|
||||
# Backend
|
||||
@ -40,6 +52,9 @@ server {
|
||||
|
||||
proxy_pass http://127.0.0.1:4000;
|
||||
proxy_redirect off;
|
||||
|
||||
access_log $GRADIDO_LOG_PATH/nginx-access.backend.log gradido_log;
|
||||
error_log $GRADIDO_LOG_PATH/nginx-error.backend.log warn;
|
||||
}
|
||||
|
||||
# Backend webhooks
|
||||
@ -54,11 +69,17 @@ server {
|
||||
# no trailing slash to keep the hook/ prefix
|
||||
proxy_pass http://127.0.0.1:4000/hook;
|
||||
proxy_redirect off;
|
||||
|
||||
access_log $GRADIDO_LOG_PATH/nginx-access.backend.hook.log gradido_log;
|
||||
error_log $GRADIDO_LOG_PATH/nginx-error.backend.hook.log warn;
|
||||
}
|
||||
|
||||
# Webhook reverse proxy
|
||||
location /hooks/ {
|
||||
proxy_pass http://127.0.0.1:9000/hooks/;
|
||||
|
||||
access_log $GRADIDO_LOG_PATH/nginx-access.hooks.log gradido_log;
|
||||
error_log $GRADIDO_LOG_PATH/nginx-error.hooks.log warn;
|
||||
}
|
||||
|
||||
# Admin Frontend
|
||||
@ -72,6 +93,9 @@ server {
|
||||
|
||||
proxy_pass http://127.0.0.1:8080/;
|
||||
proxy_redirect off;
|
||||
|
||||
access_log $GRADIDO_LOG_PATH/nginx-access.admin.log gradido_log;
|
||||
error_log $GRADIDO_LOG_PATH/nginx-error.admin.log warn;
|
||||
}
|
||||
|
||||
# TODO this could be a performance optimization
|
||||
@ -84,6 +108,4 @@ server {
|
||||
# }
|
||||
# try_files $uri $uri/ /index.html = 404;
|
||||
#}
|
||||
|
||||
#access_log /var/log/nginx/access.log main;
|
||||
}
|
||||
@ -22,15 +22,16 @@ server {
|
||||
include /etc/nginx/common/protect.conf;
|
||||
include /etc/nginx/common/protect_add_header.conf;
|
||||
|
||||
gzip on;
|
||||
|
||||
root $NGINX_UPDATE_PAGE_ROOT;
|
||||
index updating.html;
|
||||
|
||||
#location / {
|
||||
# alias $NGINX_UPDATE_PAGE_ROOT;
|
||||
# index updating.html;
|
||||
#}
|
||||
|
||||
#access_log /var/log/nginx/access.log main;
|
||||
location / {
|
||||
try_files /updating.html =404;
|
||||
}
|
||||
|
||||
access_log $GRADIDO_LOG_PATH/nginx-access.update-page.log gradido_log;
|
||||
error_log $GRADIDO_LOG_PATH/nginx-error.update-page.log warn;
|
||||
}
|
||||
|
||||
|
||||
@ -1,21 +1,22 @@
|
||||
|
||||
server {
|
||||
server_name _;
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
server_name _;
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
|
||||
include /etc/nginx/common/protect.conf;
|
||||
include /etc/nginx/common/protect_add_header.conf;
|
||||
include /etc/nginx/common/protect.conf;
|
||||
include /etc/nginx/common/protect_add_header.conf;
|
||||
|
||||
root $NGINX_UPDATE_PAGE_ROOT;
|
||||
index updating.html;
|
||||
gzip on;
|
||||
|
||||
#location / {
|
||||
# alias $NGINX_UPDATE_PAGE_ROOT;
|
||||
# index updating.html;
|
||||
#}
|
||||
root $NGINX_UPDATE_PAGE_ROOT;
|
||||
index updating.html;
|
||||
|
||||
access_log /var/log/nginx/access.log main;
|
||||
location / {
|
||||
try_files /updating.html =404;
|
||||
}
|
||||
|
||||
access_log $GRADIDO_LOG_PATH/nginx-access.update-page.log gradido_log;
|
||||
error_log $GRADIDO_LOG_PATH/nginx-error.update-page.log warn;
|
||||
}
|
||||
|
||||
|
||||
@ -1,71 +1,3 @@
|
||||
# nginx security
|
||||
sudo cat << "EOF" > ssl.conf
|
||||
##
|
||||
# SSL Settings
|
||||
##
|
||||
|
||||
# disable SSLv3(enabled by default since nginx 0.8.19) since it's less secure then TLS http://en.wikipedia.org/wiki/Secure_Sockets_Layer#SSL_3.0
|
||||
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
|
||||
|
||||
# enables server-side protection from BEAST attacks
|
||||
# http://blog.ivanristic.com/2013/09/is-beast-still-a-threat.html
|
||||
ssl_prefer_server_ciphers on;
|
||||
|
||||
# enable session resumption to improve https performance
|
||||
# http://vincent.bernat.im/en/blog/2011-ssl-session-reuse-rfc5077.html
|
||||
ssl_session_cache shared:SSL:50m;
|
||||
ssl_session_timeout 1d;
|
||||
ssl_session_tickets off;
|
||||
|
||||
# ciphers chosen for forward secrecy and compatibility
|
||||
# http://blog.ivanristic.com/2013/08/configuring-apache-nginx-and-openssl-for-forward-secrecy.html
|
||||
ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS';
|
||||
|
||||
# enable ocsp stapling (mechanism by which a site can convey certificate revocation information to visitors in a privacy-preserving, scalable manner)
|
||||
# http://blog.mozilla.org/security/2013/07/29/ocsp-stapling-in-firefox/
|
||||
resolver 8.8.8.8 8.8.4.4;
|
||||
ssl_stapling on;
|
||||
ssl_stapling_verify on;
|
||||
# ssl_trusted_certificate /etc/nginx/ssl/star_forgott_com.crt;
|
||||
|
||||
# config to enable HSTS(HTTP Strict Transport Security) https://developer.mozilla.org/en-US/docs/Security/HTTP_Strict_Transport_Security
|
||||
# to avoid ssl stripping https://en.wikipedia.org/wiki/SSL_stripping#SSL_stripping
|
||||
# also https://hstspreload.org/
|
||||
add_header Strict-Transport-Security "max-age=31536000; includeSubdomains; preload";
|
||||
EOF
|
||||
|
||||
cd /etc/nginx/conf.d
|
||||
sudo cat <<EOF > logging.conf
|
||||
log_format main '$http_x_forwarded_for - $remote_user [$time_local] '
|
||||
'"$request_method $scheme://$host$request_uri $server_protocol" '
|
||||
'$status $body_bytes_sent "$http_referer" '
|
||||
'"$http_user_agent" $request_time';
|
||||
EOF
|
||||
|
||||
# fail2ban enable blocking to many http request resulting in forbidden
|
||||
echo "fail2ban config"
|
||||
cd /etc/fail2ban/filter.d
|
||||
sudo cat <<EOF > nginx-forbidden.conf
|
||||
[Definition]
|
||||
failregex = ^.*\[error\] \d+#\d+: .* forbidden .*, client: <HOST>, .*$
|
||||
|
||||
ignoreregex =
|
||||
EOF
|
||||
|
||||
cd /etc/fail2ban/jail.d
|
||||
sudo cat <<EOF > nginx-forbidden.conf
|
||||
[nginx-forbidden]
|
||||
enabled = true
|
||||
filter = nginx-forbidden
|
||||
port = http,https
|
||||
logpath = /var/log/nginx/*error*.log
|
||||
findtime = 60
|
||||
bantime = 6000
|
||||
maxretry = 3
|
||||
EOF
|
||||
|
||||
sudo service fail2ban restart
|
||||
|
||||
# phpmyadmin
|
||||
echo "install and secure phpmyadmin"
|
||||
sudo apt install phpmyadmin
|
||||
|
||||
42
deployment/bare_metal/restore.sh
Executable file
42
deployment/bare_metal/restore.sh
Executable file
@ -0,0 +1,42 @@
|
||||
#!/bin/bash
|
||||
|
||||
# This script will shut down all services, replace the whole database with the selected backup and restart the services
|
||||
|
||||
# Find current directory & configure paths
|
||||
set -o allexport
|
||||
SCRIPT_PATH=$(realpath $0)
|
||||
SCRIPT_DIR=$(dirname $SCRIPT_PATH)
|
||||
PROJECT_ROOT=$SCRIPT_DIR/../..
|
||||
set +o allexport
|
||||
|
||||
# Parameter is a proper file?
|
||||
export BACKUP_FILE=${SCRIPT_DIR}/backup/$1
|
||||
if [ ! -f "$BACKUP_FILE" ]; then
|
||||
return "File '$BACKUP_FILE' does not exist" 2>/dev/null || exit 1
|
||||
fi
|
||||
|
||||
# Load backend .env for DB_USERNAME, DB_PASSWORD & DB_DATABASE
|
||||
# NOTE: all config values will be in process.env when starting
|
||||
# the services and will therefore take precedence over the .env
|
||||
if [ -f "$PROJECT_ROOT/backend/.env" ]; then
|
||||
export $(cat $PROJECT_ROOT/backend/.env | sed 's/#.*//g' | xargs)
|
||||
else
|
||||
export $(cat $PROJECT_ROOT/backend/.env.dist | sed 's/#.*//g' | xargs)
|
||||
fi
|
||||
|
||||
# Stop gradido-backend service
|
||||
pm2 stop gradido-backend
|
||||
|
||||
# Backup data
|
||||
mysqldump --databases --single-transaction --quick --lock-tables=false > ${SCRIPT_DIR}/backup/mariadb-restore-backup-$(date +%d-%m-%Y_%H-%M-%S).sql -u ${DB_USER} -p${DB_PASSWORD} ${DB_DATABASE}
|
||||
|
||||
# Restore Data
|
||||
mysql -u ${DB_USER} -p${DB_PASSWORD} <<EOFMYSQL
|
||||
source $BACKUP_FILE
|
||||
EOFMYSQL
|
||||
|
||||
# Update database if needed (use dev_up for seeding setups)
|
||||
yarn --cwd $PROJECT_ROOT/database up
|
||||
|
||||
# Start gradido-backend service
|
||||
pm2 start gradido-backend
|
||||
@ -4,12 +4,12 @@
|
||||
|
||||
> ssh root@gddhost.tld
|
||||
|
||||
# change default shell
|
||||
chsh
|
||||
# change root default shell
|
||||
> chsh -s /bin/bash
|
||||
# Create user `gradido`
|
||||
> useradd -d /home/gradido -m gradido
|
||||
> passwd gradido
|
||||
>> enter new
|
||||
>> enter new password twice
|
||||
|
||||
# Gives the user priviledges - this might be omitted in order to harden security
|
||||
# Care: This will require another administering user if you don't want root access.
|
||||
@ -18,6 +18,8 @@ chsh
|
||||
# You might lock yourself out, if done wrong.
|
||||
> usermod -a -G sudo gradido
|
||||
|
||||
# change gradido default shell
|
||||
> chsh -s /bin/bash gradido
|
||||
# Install sudo
|
||||
> apt-get install sudo
|
||||
# switch to the new user
|
||||
@ -67,11 +69,19 @@ chsh
|
||||
> sudo ufw enable
|
||||
|
||||
## fail2ban
|
||||
> sudo apt-get install fail2ban
|
||||
> sudo apt-get install -y fail2ban
|
||||
> sudo /etc/init.d/fail2ban restart
|
||||
|
||||
# Install gradido
|
||||
> sudo apt-get install git
|
||||
> git clone https://github.com/gradido/gradido.git
|
||||
> cd gradido/deployment/bare_metal
|
||||
|
||||
# Adjust .env
|
||||
# NOTE ';' can not be part of any value
|
||||
> cd gradido/deployment/bare_metal
|
||||
> cp .env.dist .env
|
||||
> nano .env
|
||||
>> Adjust values accordingly
|
||||
# TODO the install.sh is not yet ready to run directly - consider to use it as pattern to do it manually
|
||||
> ./install.sh
|
||||
@ -11,18 +11,18 @@ NGINX_CONFIG_DIR=$SCRIPT_DIR/nginx/sites-available
|
||||
set +o allexport
|
||||
|
||||
# Load .env or .env.dist if not present
|
||||
set -o allexport
|
||||
#TODO
|
||||
# NOTE: all config values will be in process.env when starting
|
||||
# the services and will therefore take precedence over the .env
|
||||
if [ -f "$SCRIPT_DIR/.env" ]; then
|
||||
source $SCRIPT_DIR/.env
|
||||
export $(cat $SCRIPT_DIR/.env | sed 's/#.*//g' | xargs)
|
||||
else
|
||||
source $SCRIPT_DIR/.env.dist
|
||||
export $(cat $SCRIPT_DIR/.env.dist | sed 's/#.*//g' | xargs)
|
||||
fi
|
||||
set +o allexport
|
||||
|
||||
# lock start
|
||||
if [ -f $LOCK_FILE ] ; then
|
||||
return "Already building!" 2>/dev/null || exit 1
|
||||
echo "Already building!"
|
||||
exit 1
|
||||
fi
|
||||
touch $LOCK_FILE
|
||||
|
||||
@ -80,28 +80,40 @@ fi
|
||||
# Install & build backend
|
||||
echo 'Updating backend<br>' >> $UPDATE_HTML
|
||||
cd $PROJECT_ROOT/backend
|
||||
# TODO maybe handle this differently?
|
||||
unset NODE_ENV
|
||||
yarn install
|
||||
yarn build
|
||||
# TODO maybe handle this differently?
|
||||
export NODE_ENV=production
|
||||
pm2 delete gradido-backend
|
||||
pm2 start --name gradido-backend "yarn --cwd $PROJECT_ROOT/backend start"
|
||||
pm2 start --name gradido-backend "yarn --cwd $PROJECT_ROOT/backend start" -l $GRADIDO_LOG_PATH/pm2.backend.log --log-date-format 'DD-MM HH:mm:ss.SSS'
|
||||
pm2 save
|
||||
|
||||
# Install & build frontend
|
||||
echo 'Updating frontend<br>' >> $UPDATE_HTML
|
||||
cd $PROJECT_ROOT/frontend
|
||||
# TODO maybe handle this differently?
|
||||
unset NODE_ENV
|
||||
yarn install
|
||||
yarn build
|
||||
# TODO maybe handle this differently?
|
||||
export NODE_ENV=production
|
||||
pm2 delete gradido-frontend
|
||||
pm2 start --name gradido-frontend "yarn --cwd $PROJECT_ROOT/frontend start"
|
||||
pm2 start --name gradido-frontend "yarn --cwd $PROJECT_ROOT/frontend start" -l $GRADIDO_LOG_PATH/pm2.frontend.log --log-date-format 'DD-MM HH:mm:ss.SSS'
|
||||
pm2 save
|
||||
|
||||
# Install & build admin
|
||||
echo 'Updating admin<br>' >> $UPDATE_HTML
|
||||
cd $PROJECT_ROOT/admin
|
||||
# TODO maybe handle this differently?
|
||||
unset NODE_ENV
|
||||
yarn install
|
||||
yarn build
|
||||
# TODO maybe handle this differently?
|
||||
export NODE_ENV=production
|
||||
pm2 delete gradido-admin
|
||||
pm2 start --name gradido-admin "yarn --cwd $PROJECT_ROOT/admin start"
|
||||
pm2 start --name gradido-admin "yarn --cwd $PROJECT_ROOT/admin start" -l $GRADIDO_LOG_PATH/pm2.admin.log --log-date-format 'DD-MM HH:mm:ss.SSS'
|
||||
pm2 save
|
||||
|
||||
# let nginx showing gradido
|
||||
|
||||
37
deployment/bare_metal/webhook/hooks.json.template
Normal file
37
deployment/bare_metal/webhook/hooks.json.template
Normal file
@ -0,0 +1,37 @@
|
||||
[
|
||||
{
|
||||
"id": "github",
|
||||
"execute-command": "/home/gradido/gradido/deployment/bare_metal/start.sh",
|
||||
"pass-arguments-to-command": [
|
||||
{
|
||||
"source": "string",
|
||||
"name": "$WEBHOOK_GITHUB_BRANCH"
|
||||
}
|
||||
],
|
||||
"command-working-directory": "/home/gradido/gradido/deployment/bare_metal",
|
||||
"trigger-rule": {
|
||||
"and": [
|
||||
{
|
||||
"match": {
|
||||
"type": "payload-hash-sha1",
|
||||
"secret": "$WEBHOOK_GITHUB_SECRET",
|
||||
"parameter": {
|
||||
"source": "header",
|
||||
"name": "X-Hub-Signature"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"match": {
|
||||
"type": "value",
|
||||
"value": "refs/heads/$WEBHOOK_GITHUB_BRANCH",
|
||||
"parameter": {
|
||||
"source": "payload",
|
||||
"name": "ref"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
@ -1,4 +1,3 @@
|
||||
GRAPHQL_URI=http://localhost:4000/graphql
|
||||
GRAPHQL_URI=http://localhost/graphql
|
||||
DEFAULT_PUBLISHER_ID=2896
|
||||
#BUILD_COMMIT=0000000
|
||||
ADMIN_AUTH_URL=http://localhost/admin/authenticate?token=$1
|
||||
ADMIN_AUTH_URL=http://localhost/admin/authenticate?token={token}
|
||||
3
frontend/.env.template
Normal file
3
frontend/.env.template
Normal file
@ -0,0 +1,3 @@
|
||||
GRAPHQL_URI=$GRAPHQL_URI
|
||||
DEFAULT_PUBLISHER_ID=2896
|
||||
ADMIN_AUTH_URL=$ADMIN_AUTH_URL
|
||||
@ -38,14 +38,19 @@
|
||||
</b-link>
|
||||
</div>
|
||||
<b-nav-item to="/overview" class="mb-3">
|
||||
<b-icon icon="house" aria-hidden="true"></b-icon>
|
||||
{{ $t('overview') }}
|
||||
</b-nav-item>
|
||||
<b-nav-item to="/send" class="mb-3">{{ $t('send') }}</b-nav-item>
|
||||
<b-nav-item to="/send" class="mb-3">
|
||||
<b-icon icon="arrow-left-right" aria-hidden="true"></b-icon>
|
||||
{{ $t('send') }}
|
||||
</b-nav-item>
|
||||
<b-nav-item to="/transactions" class="mb-3">
|
||||
<b-icon icon="layout-text-sidebar-reverse" aria-hidden="true"></b-icon>
|
||||
{{ $t('transactions') }}
|
||||
</b-nav-item>
|
||||
<b-nav-item to="/profile" class="mb-3">
|
||||
<b-icon icon="gear-fill" aria-hidden="true"></b-icon>
|
||||
<b-icon icon="gear" aria-hidden="true"></b-icon>
|
||||
{{ $t('site.navbar.my-profil') }}
|
||||
</b-nav-item>
|
||||
<br />
|
||||
@ -55,7 +60,7 @@
|
||||
<b-badge v-if="!$store.state.hasElopage" pill variant="danger">!</b-badge>
|
||||
</b-nav-item>
|
||||
<b-nav-item class="mb-3" v-if="$store.state.isAdmin" @click="$emit('admin')">
|
||||
<b-icon icon="link45deg" aria-hidden="true"></b-icon>
|
||||
<b-icon icon="shield-check" aria-hidden="true"></b-icon>
|
||||
{{ $t('admin_area') }}
|
||||
</b-nav-item>
|
||||
<b-nav-item class="mb-3" @click="$emit('logout')">
|
||||
|
||||
@ -4,11 +4,20 @@
|
||||
<p></p>
|
||||
<div class="mb-6">
|
||||
<b-nav vertical class="w-200">
|
||||
<b-nav-item to="/overview" class="mb-3" active>{{ $t('overview') }}</b-nav-item>
|
||||
<b-nav-item to="/send" class="mb-3">{{ $t('send') }}</b-nav-item>
|
||||
<b-nav-item to="/transactions" class="mb-3">{{ $t('transactions') }}</b-nav-item>
|
||||
<b-nav-item to="/overview" class="mb-3" active>
|
||||
<b-icon icon="house" aria-hidden="true"></b-icon>
|
||||
{{ $t('overview') }}
|
||||
</b-nav-item>
|
||||
<b-nav-item to="/send" class="mb-3">
|
||||
<b-icon icon="arrow-left-right" aria-hidden="true"></b-icon>
|
||||
{{ $t('send') }}
|
||||
</b-nav-item>
|
||||
<b-nav-item to="/transactions" class="mb-3">
|
||||
<b-icon icon="layout-text-sidebar-reverse" aria-hidden="true"></b-icon>
|
||||
{{ $t('transactions') }}
|
||||
</b-nav-item>
|
||||
<b-nav-item to="/profile" class="mb-3">
|
||||
<b-icon icon="gear-fill" aria-hidden="true"></b-icon>
|
||||
<b-icon icon="gear" aria-hidden="true"></b-icon>
|
||||
{{ $t('site.navbar.my-profil') }}
|
||||
</b-nav-item>
|
||||
</b-nav>
|
||||
@ -20,7 +29,7 @@
|
||||
<b-badge v-if="!$store.state.hasElopage" pill variant="danger">!</b-badge>
|
||||
</b-nav-item>
|
||||
<b-nav-item class="mb-3" v-if="$store.state.isAdmin" @click="$emit('admin')">
|
||||
<b-icon icon="link45deg" aria-hidden="true"></b-icon>
|
||||
<b-icon icon="shield-check" aria-hidden="true"></b-icon>
|
||||
{{ $t('admin_area') }}
|
||||
</b-nav-item>
|
||||
<b-nav-item class="mb-3" @click="$emit('logout')">
|
||||
|
||||
@ -19,8 +19,8 @@ const environment = {
|
||||
}
|
||||
|
||||
const endpoints = {
|
||||
GRAPHQL_URI: process.env.GRAPHQL_URI || 'http://localhost:4000/graphql',
|
||||
ADMIN_AUTH_URL: process.env.ADMIN_AUTH_URL || 'http://localhost/admin/authenticate?token=$1',
|
||||
GRAPHQL_URI: process.env.GRAPHQL_URI || 'http://localhost/graphql',
|
||||
ADMIN_AUTH_URL: process.env.ADMIN_AUTH_URL || 'http://localhost/admin/authenticate?token={token}',
|
||||
}
|
||||
|
||||
const options = {}
|
||||
|
||||
@ -100,6 +100,7 @@ export default {
|
||||
})
|
||||
.catch((error) => {
|
||||
this.pending = true
|
||||
this.transactionCount = -1
|
||||
this.$toasted.global.error(error.message)
|
||||
// what to do when loading balance fails?
|
||||
})
|
||||
@ -108,7 +109,7 @@ export default {
|
||||
this.balance -= ammount
|
||||
},
|
||||
admin() {
|
||||
window.location.assign(CONFIG.ADMIN_AUTH_URL.replace('$1', this.$store.state.token))
|
||||
window.location.assign(CONFIG.ADMIN_AUTH_URL.replace('{token}', this.$store.state.token))
|
||||
this.$store.dispatch('logout') // logout without redirect
|
||||
},
|
||||
setVisible(bool) {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div>
|
||||
<div>
|
||||
<div class="container-fluid">
|
||||
<b-row>
|
||||
<b-col class="col-6">
|
||||
<b-row>
|
||||
|
||||
@ -56,16 +56,20 @@ describe('GddTransactionList', () => {
|
||||
})
|
||||
})
|
||||
it('Transactions Array is empty, 0 transactions', () => {
|
||||
expect(wrapper.find('div.test-empty-transactionlist').text()).toContain(
|
||||
'error.empty-transactionlist',
|
||||
)
|
||||
expect(wrapper.find('div.test-empty-transactionlist').exists()).toBe(false)
|
||||
})
|
||||
})
|
||||
|
||||
describe('without any properties', () => {
|
||||
beforeEach(async () => {
|
||||
await wrapper.setProps({
|
||||
transactions: [],
|
||||
transactionCount: -1,
|
||||
})
|
||||
})
|
||||
it('renders text saying that there are error.empty-transactionlist ', () => {
|
||||
expect(wrapper.find('div.gdd-transaction-list').text()).toContain(
|
||||
'error.empty-transactionlist',
|
||||
'transaction.nullTransactions',
|
||||
)
|
||||
})
|
||||
it('renders text saying that there are no transaction.nullTransactions', () => {
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
{{ $t('error.no-transactionlist') }}
|
||||
</small>
|
||||
</div>
|
||||
<div v-if="!transactionCount" class="test-empty-transactionlist text-right">
|
||||
<div v-if="transactionCount < 0" class="test-empty-transactionlist text-right">
|
||||
<b-icon icon="exclamation-triangle" class="mr-2" style="color: red"></b-icon>
|
||||
<small>{{ $t('error.empty-transactionlist') }}</small>
|
||||
</div>
|
||||
@ -134,7 +134,7 @@
|
||||
:per-page="pageSize"
|
||||
:total-rows="transactionCount"
|
||||
></pagination-buttons>
|
||||
<div v-if="transactionCount === 0" class="mt-4 text-center">
|
||||
<div v-if="transactionCount < 0" class="mt-4 text-center">
|
||||
<span>{{ $t('transaction.nullTransactions') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -3,7 +3,10 @@
|
||||
<div>
|
||||
<b-row class="mb-4 text-right">
|
||||
<b-col class="text-right">
|
||||
<a @click="showUserData ? (showUserData = !showUserData) : cancelEdit()">
|
||||
<a
|
||||
class="cursor-pointer"
|
||||
@click="showUserData ? (showUserData = !showUserData) : cancelEdit()"
|
||||
>
|
||||
<span class="pointer mr-3">{{ $t('settings.name.change-name') }}</span>
|
||||
<b-icon v-if="showUserData" class="pointer ml-3" icon="pencil"></b-icon>
|
||||
<b-icon v-else icon="x-circle" class="pointer ml-3" variant="danger"></b-icon>
|
||||
@ -130,4 +133,8 @@ export default {
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style></style>
|
||||
<style>
|
||||
.cursor-pointer {
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -3,7 +3,10 @@
|
||||
<div>
|
||||
<b-row class="mb-4 text-right">
|
||||
<b-col class="text-right">
|
||||
<a @click="showPassword ? (showPassword = !showPassword) : cancelEdit()">
|
||||
<a
|
||||
class="cursor-pointer"
|
||||
@click="showPassword ? (showPassword = !showPassword) : cancelEdit()"
|
||||
>
|
||||
<span class="pointer mr-3">{{ $t('settings.password.change-password') }}</span>
|
||||
<b-icon v-if="showPassword" class="pointer ml-3" icon="pencil"></b-icon>
|
||||
<b-icon v-else icon="x-circle" class="pointer ml-3" variant="danger"></b-icon>
|
||||
@ -91,3 +94,8 @@ export default {
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.cursor-pointer {
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -3,7 +3,10 @@
|
||||
<div>
|
||||
<b-row class="mb-4 text-right">
|
||||
<b-col class="text-right">
|
||||
<a @click="showLanguage ? (showLanguage = !showLanguage) : cancelEdit()">
|
||||
<a
|
||||
class="cursor-pointer"
|
||||
@click="showLanguage ? (showLanguage = !showLanguage) : cancelEdit()"
|
||||
>
|
||||
<span class="pointer mr-3">{{ $t('settings.language.changeLanguage') }}</span>
|
||||
<b-icon v-if="showLanguage" class="pointer ml-3" icon="pencil"></b-icon>
|
||||
<b-icon v-else icon="x-circle" class="pointer ml-3" variant="danger"></b-icon>
|
||||
@ -110,3 +113,8 @@ export default {
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.cursor-pointer {
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -88,4 +88,22 @@ describe('Thx', () => {
|
||||
expect(wrapper.find('a.btn').attributes('href')).toBe('/overview')
|
||||
})
|
||||
})
|
||||
|
||||
describe('coming from /login', () => {
|
||||
beforeEach(() => {
|
||||
wrapper = Wrapper(createMockObject('login'))
|
||||
})
|
||||
|
||||
it('renders the thanks text', () => {
|
||||
expect(wrapper.find('p.h4').text()).toBe('site.thx.activateEmail')
|
||||
})
|
||||
|
||||
it('renders the thanks redirect button', () => {
|
||||
expect(wrapper.find('a.btn').text()).toBe('login')
|
||||
})
|
||||
|
||||
it('links the redirect button to /login', () => {
|
||||
expect(wrapper.find('a.btn').attributes('href')).toBe('/login')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@ -45,6 +45,8 @@ const textFields = {
|
||||
login: {
|
||||
headline: 'site.thx.errorTitle',
|
||||
subtitle: 'site.thx.activateEmail',
|
||||
button: 'login',
|
||||
linkTo: '/login',
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user