Merge branch 'master' into login_call_unsecureLogin

This commit is contained in:
Ulf Gebhardt 2021-11-22 16:26:08 +01:00 committed by GitHub
commit 82ea3dc11a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
36 changed files with 15262 additions and 4 deletions

View File

@ -29,6 +29,32 @@ jobs:
name: docker-frontend-test
path: /tmp/frontend.tar
##############################################################################
# JOB: DOCKER BUILD TEST ADMIN INTERFACE #####################################
##############################################################################
build_test_admin:
name: Docker Build Test - Admin Interface
runs-on: ubuntu-latest
#needs: [nothing]
steps:
##########################################################################
# CHECKOUT CODE ##########################################################
##########################################################################
- name: Checkout code
uses: actions/checkout@v2
##########################################################################
# ADMIN INTERFACE ########################################################
##########################################################################
- name: Admin | Build `test` image
run: |
docker build --target test -t "gradido/admin:test" admin/
docker save "gradido/admin:test" > /tmp/admin.tar
- name: Upload Artifact
uses: actions/upload-artifact@v2
with:
name: docker-admin-test
path: /tmp/admin.tar
##############################################################################
# JOB: DOCKER BUILD TEST BACKEND #############################################
##############################################################################
@ -240,7 +266,36 @@ jobs:
run: docker run --rm gradido/frontend:test yarn run lint
##############################################################################
# JOB: LINT BACKEND #########################################################
# JOB: LINT ADMIN INTERFACE ##################################################
##############################################################################
lint_admin:
name: Lint - Admin Interface
runs-on: ubuntu-latest
needs: [build_test_admin]
steps:
##########################################################################
# CHECKOUT CODE ##########################################################
##########################################################################
- name: Checkout code
uses: actions/checkout@v2
##########################################################################
# DOWNLOAD DOCKER IMAGE ##################################################
##########################################################################
- name: Download Docker Image (Admin Interface)
uses: actions/download-artifact@v2
with:
name: docker-admin-test
path: /tmp
- name: Load Docker Image
run: docker load < /tmp/admin.tar
##########################################################################
# LINT ADMIN INTERFACE ###################################################
##########################################################################
- name: Admin Interface | Lint
run: docker run --rm gradido/admin:test yarn run lint
##############################################################################
# JOB: LINT BACKEND ##########################################################
##############################################################################
lint_backend:
name: Lint - Backend
@ -347,6 +402,48 @@ jobs:
min_coverage: 86
token: ${{ github.token }}
##############################################################################
# JOB: UNIT TEST ADMIN INTERFACE #############################################
##############################################################################
unit_test_admin:
name: Unit tests - Admin Interface
runs-on: ubuntu-latest
needs: [build_test_admin]
steps:
##########################################################################
# CHECKOUT CODE ##########################################################
##########################################################################
- name: Checkout code
uses: actions/checkout@v2
##########################################################################
# DOWNLOAD DOCKER IMAGES #################################################
##########################################################################
- name: Download Docker Image (Admin Interface)
uses: actions/download-artifact@v2
with:
name: docker-admin-test
path: /tmp
- name: Load Docker Image
run: docker load < /tmp/admin.tar
##########################################################################
# UNIT TESTS ADMIN INTERFACE #############################################
##########################################################################
- name: Admin Interface | Unit tests
run: |
docker run -v ~/coverage:/app/coverage --rm gradido/admin:test yarn run test
cp -r ~/coverage ./coverage
##########################################################################
# COVERAGE CHECK ADMIN INTERFACE #########################################
##########################################################################
- name: Admin Interface | Coverage check
uses: webcraftmedia/coverage-check-action@master
with:
report_name: Coverage Admin Interface
type: lcov
result_path: ./coverage/lcov.info
min_coverage: 65
token: ${{ github.token }}
##############################################################################
# JOB: UNIT TEST BACKEND ####################################################
##############################################################################

3
admin/.dockerignore Normal file
View File

@ -0,0 +1,3 @@
node_modules
.git
.gitignore

4
admin/.eslintignore Normal file
View File

@ -0,0 +1,4 @@
node_modules
coverage
**/*.min.js
dist

26
admin/.eslintrc.js Normal file
View File

@ -0,0 +1,26 @@
module.exports = {
root: true,
env: {
browser: true,
node: true,
jest: true,
},
parserOptions: {
parser: 'babel-eslint',
},
extends: ['standard', 'plugin:vue/essential', 'plugin:prettier/recommended'],
// required to lint *.vue files
plugins: ['vue', 'prettier', 'jest'],
// add your custom rules here
rules: {
'no-console': ['error'],
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
'vue/component-name-in-template-casing': ['error', 'kebab-case'],
'prettier/prettier': [
'error',
{
htmlWhitespaceSensitivity: 'ignore',
},
],
},
}

15
admin/.gitattributes vendored Normal file
View File

@ -0,0 +1,15 @@
# Auto detect text files and perform LF normalization
*.scss linguist-language=Vue
*.css linguist-language=Vue
# Standard to msysgit
*.doc diff=astextplain
*.DOC diff=astextplain
*.docx diff=astextplain
*.DOCX diff=astextplain
*.dot diff=astextplain
*.DOT diff=astextplain
*.pdf diff=astextplain
*.PDF diff=astextplain
*.rtf diff=astextplain
*.RTF diff=astextplain

11
admin/.gitignore vendored Normal file
View File

@ -0,0 +1,11 @@
node_modules/
dist/
.cache/
.env
# coverage folder
coverage/
# emacs
*~

8
admin/.prettierrc.js Normal file
View File

@ -0,0 +1,8 @@
module.exports = {
semi: false,
printWidth: 100,
singleQuote: true,
trailingComma: "all",
tabWidth: 2,
bracketSpacing: true
};

98
admin/Dockerfile Normal file
View File

@ -0,0 +1,98 @@
##################################################################################
# BASE ###########################################################################
##################################################################################
FROM node:14.17.0-alpine3.10 as base
# ENVs (available in production aswell, can be overwritten by commandline or env file)
## DOCKER_WORKDIR would be a classical ARG, but that is not multi layer persistent - shame
ENV DOCKER_WORKDIR="/app"
## We Cannot do `$(date -u +'%Y-%m-%dT%H:%M:%SZ')` here so we use unix timestamp=0
ENV BUILD_DATE="1970-01-01T00:00:00.00Z"
## We cannot do $(npm run version).${BUILD_NUMBER} here so we default to 0.0.0.0
ENV BUILD_VERSION="0.0.0.0"
## We cannot do `$(git rev-parse --short HEAD)` here so we default to 0000000
ENV BUILD_COMMIT="0000000"
## SET NODE_ENV
ENV NODE_ENV="production"
## App relevant Envs
ENV PORT="8080"
# Labels
LABEL org.label-schema.build-date="${BUILD_DATE}"
LABEL org.label-schema.name="gradido:admin"
LABEL org.label-schema.description="Gradido Vue Admin Interface"
LABEL org.label-schema.usage="https://github.com/gradido/gradido/admin/README.md"
LABEL org.label-schema.url="https://gradido.net"
LABEL org.label-schema.vcs-url="https://github.com/gradido/gradido/backend"
LABEL org.label-schema.vcs-ref="${BUILD_COMMIT}"
LABEL org.label-schema.vendor="gradido Community"
LABEL org.label-schema.version="${BUILD_VERSION}"
LABEL org.label-schema.schema-version="1.0"
LABEL maintainer="support@ogradido.net"
# Install Additional Software
## install: git
#RUN apk --no-cache add git
# Settings
## Expose Container Port
EXPOSE ${PORT}
## Workdir
RUN mkdir -p ${DOCKER_WORKDIR}
WORKDIR ${DOCKER_WORKDIR}
##################################################################################
# DEVELOPMENT (Connected to the local environment, to reload on demand) ##########
##################################################################################
FROM base as development
# We don't need to copy or build anything since we gonna bind to the
# local filesystem which will need a rebuild anyway
# Run command
# (for development we need to execute yarn install since the
# node_modules are on another volume and need updating)
CMD /bin/sh -c "yarn install && yarn run dev"
##################################################################################
# BUILD (Does contain all files and is therefore bloated) ########################
##################################################################################
FROM base as build
# Copy everything
COPY . .
# yarn install
RUN yarn install --production=false --frozen-lockfile --non-interactive
# yarn build
RUN yarn run build
##################################################################################
# TEST ###########################################################################
##################################################################################
FROM build as test
# Install Additional Software
RUN apk add --no-cache bash jq
# Run command
CMD /bin/sh -c "yarn run dev"
##################################################################################
# PRODUCTION (Does contain only "binary"- and static-files to reduce image size) #
##################################################################################
FROM base as production
# Copy "binary"-files from build image
COPY --from=build ${DOCKER_WORKDIR}/dist ./dist
# We also copy the node_modules express and serve-static for the run script
COPY --from=build ${DOCKER_WORKDIR}/node_modules ./node_modules
# Copy static files
COPY --from=build ${DOCKER_WORKDIR}/public ./public
# Copy package.json for script definitions (lock file should not be needed)
COPY --from=build ${DOCKER_WORKDIR}/package.json ./package.json
# Copy run scripts run/
COPY --from=build ${DOCKER_WORKDIR}/run ./run
# Run command
CMD /bin/sh -c "yarn run start"

26
admin/README.md Normal file
View File

@ -0,0 +1,26 @@
# admin
## Project setup
```
yarn install
```
### Compiles and hot-reloads for development
```
yarn serve
```
### Compiles and minifies for production
```
yarn build
```
### Lints and fixes files
```
yarn lint
```
### Unit tests
```
yarn test
```

4
admin/babel.config.js Normal file
View File

@ -0,0 +1,4 @@
module.exports = {
presets: ['@babel/preset-env'],
plugins: ['transform-require-context'],
}

25
admin/jest.config.js Normal file
View File

@ -0,0 +1,25 @@
module.exports = {
verbose: true,
collectCoverageFrom: ['src/**/*.{js,vue}', '!**/node_modules/**', '!**/?(*.)+(spec|test).js?(x)'],
moduleFileExtensions: [
'js',
// 'jsx',
'json',
'vue',
],
// coverageReporters: ['lcov', 'text'],
moduleNameMapper: {
'^@/(.*)$': '<rootDir>/src/$1',
'\\.(css|less)$': 'identity-obj-proxy',
},
transform: {
'^.+\\.vue$': 'vue-jest',
'^.+\\.(js|jsx)?$': 'babel-jest',
'<rootDir>/node_modules/vee-validate/dist/rules': 'babel-jest',
},
setupFiles: ['<rootDir>/test/testSetup.js'],
testMatch: ['**/?(*.)+(spec|test).js?(x)'],
// snapshotSerializers: ['jest-serializer-vue'],
transformIgnorePatterns: ['<rootDir>/node_modules/(?!vee-validate/dist/rules)'],
testEnvironment: 'jest-environment-jsdom-sixteen',
}

70
admin/package.json Normal file
View File

@ -0,0 +1,70 @@
{
"name": "admin",
"description": "Administraion Interface for Gradido",
"main": "index.js",
"author": "Moriz Wahl",
"version": "0.1.0",
"license": "MIT",
"private": false,
"scripts": {
"start": "node run/server.js",
"serve": "vue-cli-service serve --open",
"dev": "yarn run serve",
"build": "vue-cli-service build",
"lint": "eslint --ext .js,.vue .",
"test": "jest --coverage"
},
"dependencies": {
"@babel/core": "^7.15.8",
"@babel/node": "^7.15.8",
"@babel/preset-env": "^7.15.8",
"@vue/cli-plugin-unit-jest": "^4.5.14",
"@vue/eslint-config-prettier": "^6.0.0",
"@vue/test-utils": "^1.2.2",
"apollo-boost": "^0.4.9",
"babel-core": "7.0.0-bridge.0",
"babel-jest": "^27.3.1",
"babel-plugin-component": "^1.1.1",
"babel-preset-env": "^1.7.0",
"babel-preset-vue": "^2.0.2",
"bootstrap": "^5.1.3",
"bootstrap-vue": "^2.21.2",
"core-js": "^3.6.5",
"dotenv-webpack": "^7.0.3",
"graphql": "^15.6.1",
"jest": "26.6.3",
"regenerator-runtime": "^0.13.9",
"stats-webpack-plugin": "^0.7.0",
"vue": "^2.6.11",
"vue-apollo": "^3.0.8",
"vue-i18n": "^8.26.5",
"vue-jest": "^3.0.7",
"vue-router": "^3.5.3",
"vuex": "^3.6.2"
},
"devDependencies": {
"@babel/eslint-parser": "^7.15.8",
"@vue/cli-plugin-babel": "~4.5.0",
"@vue/cli-plugin-eslint": "~4.5.0",
"@vue/cli-service": "~4.5.0",
"babel-eslint": "^10.1.0",
"babel-plugin-transform-require-context": "^0.1.1",
"eslint": "7.25.0",
"eslint-config-prettier": "^8.3.0",
"eslint-config-standard": "^16.0.3",
"eslint-loader": "^4.0.2",
"eslint-plugin-import": "^2.25.2",
"eslint-plugin-jest": "^25.2.2",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-prettier": "3.3.1",
"eslint-plugin-promise": "^5.1.1",
"eslint-plugin-vue": "^7.20.0",
"jest-environment-jsdom-sixteen": "^2.0.0",
"vue-template-compiler": "^2.6.11"
},
"browserslist": [
"> 1%",
"last 2 versions",
"not ie <= 10"
]
}

BIN
admin/public/favicon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

22
admin/public/index.html Normal file
View File

@ -0,0 +1,22 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link rel="icon" type="image/png" sizes="96x96" href="<%= webpackConfig.output.publicPath %>favicon.png">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<title>Gradido Admin Interface</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
<!-- Fonts -->
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.6.3/css/all.css" integrity="sha384-UHRtZLI+pbxtHCWp1t77Bi1L4ZtiqrqD80Kn4Z8NTSRyMA2Fd33n5dQ8lWUE00s/" crossorigin="anonymous">
</head>
<body>
<div class="wrapper" id="app">
</div>
<!-- built files will be auto injected -->
</body>
</html>

15
admin/run/server.js Normal file
View File

@ -0,0 +1,15 @@
// Imports
const express = require('express')
const serveStatic = require('serve-static')
// Port
const port = process.env.PORT || 8080
// Express Server
const app = express()
// eslint-disable-next-line node/no-path-concat
app.use(serveStatic(__dirname + '/../dist'))
app.listen(port)
// eslint-disable-next-line no-console
console.log(`http://admin:${port} server started.`)

68
admin/src/App.spec.js Normal file
View File

@ -0,0 +1,68 @@
import { mount } from '@vue/test-utils'
import App from './App'
const localVue = global.localVue
const storeCommitMock = jest.fn()
const mocks = {
$store: {
commit: storeCommitMock,
},
}
const localStorageMock = (() => {
let store = {}
return {
getItem: (key) => {
return store[key] || null
},
setItem: (key, value) => {
store[key] = value.toString()
},
removeItem: (key) => {
delete store[key]
},
clear: () => {
store = {}
},
}
})()
describe('App', () => {
let wrapper
const Wrapper = () => {
return mount(App, { localVue, mocks })
}
describe('mount', () => {
beforeEach(() => {
wrapper = Wrapper()
})
it('has a div with id "app"', () => {
expect(wrapper.find('div#app').exists()).toBeTruthy()
})
})
describe('window localStorage is undefined', () => {
it('does not commit a token to the store', () => {
expect(storeCommitMock).not.toBeCalled()
})
})
describe('with token in local storage', () => {
beforeEach(() => {
Object.defineProperty(window, 'localStorage', {
value: localStorageMock,
})
window.localStorage.setItem('vuex', JSON.stringify({ token: 1234 }))
})
it.skip('commits the token to the store', () => {
expect(storeCommitMock).toBeCalledWith('token', 1234)
})
})
})

9
admin/src/App.vue Normal file
View File

@ -0,0 +1,9 @@
<template>
<div id="app"></div>
</template>
<script>
export default {
name: 'App',
}
</script>

View File

@ -0,0 +1,22 @@
import { mount } from '@vue/test-utils'
import NotFoundPage from './NotFoundPage'
const localVue = global.localVue
describe('NotFoundPage', () => {
let wrapper
const Wrapper = () => {
return mount(NotFoundPage, { localVue })
}
describe('mount', () => {
beforeEach(() => {
wrapper = Wrapper()
})
it('has a svg', () => {
expect(wrapper.find('svg').exists()).toBeTruthy()
})
})
})

File diff suppressed because it is too large Load Diff

33
admin/src/config/index.js Normal file
View File

@ -0,0 +1,33 @@
// ATTENTION: DO NOT PUT ANY SECRETS IN HERE (or the .env).
// The whole contents is exposed to the client
// Load Package Details for some default values
const pkg = require('../../package')
const version = {
APP_VERSION: pkg.version,
BUILD_COMMIT: process.env.BUILD_COMMIT || null,
// self reference of `version.BUILD_COMMIT` is not possible at this point, hence the duplicate code
BUILD_COMMIT_SHORT: (process.env.BUILD_COMMIT || '0000000').substr(0, 7),
}
const environment = {
NODE_ENV: process.env.NODE_ENV,
DEBUG: process.env.NODE_ENV !== 'production' || false,
PRODUCTION: process.env.NODE_ENV === 'production' || false,
}
const server = {
GRAPHQL_URI: process.env.GRAPHQL_URI || 'http://localhost:4000/graphql',
}
const options = {}
const CONFIG = {
...version,
...environment,
...server,
...options,
}
export default CONFIG

89
admin/src/i18n.js Normal file
View File

@ -0,0 +1,89 @@
import Vue from 'vue'
import VueI18n from 'vue-i18n'
Vue.use(VueI18n)
const loadLocaleMessages = () => {
const locales = require.context('./locales', true, /[A-Za-z0-9-_,\s]+\.json$/i)
const messages = {}
locales.keys().forEach((key) => {
const matched = key.match(/([A-Za-z0-9-_]+)\./i)
if (matched && matched.length > 1) {
const locale = matched[1]
messages[locale] = locales(key)
}
})
return messages
}
const numberFormats = {
en: {
decimal: {
style: 'decimal',
minimumFractionDigits: 2,
maximumFractionDigits: 2,
},
ungroupedDecimal: {
style: 'decimal',
minimumFractionDigits: 2,
maximumFractionDigits: 2,
useGrouping: false,
},
},
de: {
decimal: {
style: 'decimal',
minimumFractionDigits: 2,
maximumFractionDigits: 2,
},
ungroupedDecimal: {
style: 'decimal',
minimumFractionDigits: 2,
maximumFractionDigits: 2,
useGrouping: false,
},
},
}
const dateTimeFormats = {
en: {
short: {
year: 'numeric',
month: 'numeric',
day: 'numeric',
},
long: {
year: 'numeric',
month: 'short',
day: 'numeric',
weekday: 'short',
hour: 'numeric',
minute: 'numeric',
},
},
de: {
short: {
day: 'numeric',
month: 'numeric',
year: 'numeric',
},
long: {
day: 'numeric',
month: 'short',
year: 'numeric',
weekday: 'short',
hour: 'numeric',
minute: 'numeric',
},
},
}
const i18n = new VueI18n({
locale: 'en',
fallbackLocale: 'en',
messages: loadLocaleMessages(),
numberFormats,
dateTimeFormats,
})
export default i18n

View File

@ -0,0 +1 @@
{}

View File

@ -0,0 +1 @@
{}

63
admin/src/main.js Normal file
View File

@ -0,0 +1,63 @@
import Vue from 'vue'
import App from './App.vue'
// without this async calls are not working
import 'regenerator-runtime'
import store from './store/store'
import router from './router/router'
import addNavigationGuards from './router/guards'
import i18n from './i18n'
import { ApolloClient, ApolloLink, InMemoryCache, HttpLink } from 'apollo-boost'
import VueApollo from 'vue-apollo'
import CONFIG from './config'
import { BootstrapVue } from 'bootstrap-vue'
const httpLink = new HttpLink({ uri: CONFIG.GRAPHQL_URI })
const authLink = new ApolloLink((operation, forward) => {
const token = store.state.token
operation.setContext({
headers: {
Authorization: token && token.length > 0 ? `Bearer ${token}` : '',
},
})
return forward(operation)
/* .map((response) => {
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 !== '/login') router.push('/login')
return response
}
const newToken = operation.getContext().response.headers.get('token')
if (newToken) store.commit('token', newToken)
return response
}) */
})
const apolloClient = new ApolloClient({
link: authLink.concat(httpLink),
cache: new InMemoryCache(),
})
const apolloProvider = new VueApollo({
defaultClient: apolloClient,
})
Vue.use(BootstrapVue)
addNavigationGuards(router, store)
new Vue({
router,
store,
i18n,
apolloProvider,
render: (h) => h(App),
}).$mount('#app')

56
admin/src/main.test.js Normal file
View File

@ -0,0 +1,56 @@
import { ApolloClient, ApolloLink, InMemoryCache, HttpLink } from 'apollo-boost'
import './main'
import CONFIG from './config'
import Vue from 'vue'
import Vuex from 'vuex'
import VueI18n from 'vue-i18n'
jest.mock('vue')
jest.mock('vuex')
jest.mock('vue-i18n')
const storeMock = jest.fn()
Vuex.Store = storeMock
jest.mock('apollo-boost', () => {
return {
__esModule: true,
ApolloClient: jest.fn(),
ApolloLink: jest.fn(() => {
return { concat: jest.fn() }
}),
InMemoryCache: jest.fn(),
HttpLink: jest.fn(),
}
})
describe('main', () => {
it('calls the HttpLink', () => {
expect(HttpLink).toBeCalledWith({ uri: CONFIG.GRAPHQL_URI })
})
it('calls the ApolloLink', () => {
expect(ApolloLink).toBeCalled()
})
it('calls the ApolloClient', () => {
expect(ApolloClient).toBeCalled()
})
it('calls the InMemoryCache', () => {
expect(InMemoryCache).toBeCalled()
})
it('calls Vue', () => {
expect(Vue).toBeCalled()
})
it('calls VueI18n', () => {
expect(VueI18n).toBeCalled()
})
it.skip('creates a store', () => {
expect(storeMock).toBeCalled()
})
})

View File

@ -0,0 +1,12 @@
const addNavigationGuards = (router, store) => {
router.beforeEach((to, from, next) => {
// handle authentication
if (to.meta.requiresAuth && !store.state.token) {
next({ path: '/not-found' })
} else {
next()
}
})
}
export default addNavigationGuards

View File

@ -0,0 +1,23 @@
import Vue from 'vue'
import VueRouter from 'vue-router'
import routes from './routes'
Vue.use(VueRouter)
const router = new VueRouter({
base: '/admin',
routes,
linkActiveClass: 'active',
mode: 'history',
scrollBehavior: (to, from, savedPosition) => {
if (savedPosition) {
return savedPosition
}
if (to.hash) {
return { selector: to.hash }
}
return { x: 0, y: 0 }
},
})
export default router

View File

@ -0,0 +1,15 @@
import NotFound from '@/components/NotFoundPage.vue'
const routes = [
{
path: '/',
/*
meta: {
requiresAuth: true,
},
*/
},
{ path: '*', component: NotFound },
]
export default routes

19
admin/src/store/store.js Normal file
View File

@ -0,0 +1,19 @@
import Vuex from 'vuex'
import Vue from 'vue'
Vue.use(Vuex)
export const mutations = {
token: (state, token) => {
state.token = token
},
}
const store = new Vuex.Store({
mutations,
state: {
token: 'some-token',
},
})
export default store

View File

@ -0,0 +1,15 @@
import { mutations } from './store'
const { token } = mutations
describe('Vuex store', () => {
describe('mutations', () => {
describe('token', () => {
it('sets the state of token', () => {
const state = { token: null }
token(state, '1234')
expect(state.token).toEqual('1234')
})
})
})
})

15
admin/test/testSetup.js Normal file
View File

@ -0,0 +1,15 @@
import { createLocalVue } from '@vue/test-utils'
import Vue from 'vue'
import { BootstrapVue } from 'bootstrap-vue'
// without this async calls are not working
import 'regenerator-runtime'
global.localVue = createLocalVue()
global.localVue.use(BootstrapVue)
// throw errors for vue warnings to force the programmers to take care about warnings
Vue.config.warnHandler = (w) => {
throw new Error(w)
}

51
admin/vue.config.js Normal file
View File

@ -0,0 +1,51 @@
const path = require('path')
const webpack = require('webpack')
const Dotenv = require('dotenv-webpack')
const StatsPlugin = require('stats-webpack-plugin')
// vue.config.js
module.exports = {
devServer: {
port: process.env.PORT || 8080,
},
pluginOptions: {
i18n: {
locale: 'de',
fallbackLocale: 'de',
localeDir: 'locales',
enableInSFC: false,
},
},
lintOnSave: true,
publicPath: '/admin',
configureWebpack: {
// Set up all the aliases we use in our app.
resolve: {
alias: {
assets: path.join(__dirname, 'src/assets'),
},
},
plugins: [
// .env and Environment Variables
new Dotenv(),
new webpack.DefinePlugin({
// Those are Environment Variables transmitted via Docker and are only available when defined here aswell
// 'process.env.DOCKER_WORKDIR': JSON.stringify(process.env.DOCKER_WORKDIR),
// 'process.env.BUILD_DATE': JSON.stringify(process.env.BUILD_DATE),
// 'process.env.BUILD_VERSION': JSON.stringify(process.env.BUILD_VERSION),
'process.env.BUILD_COMMIT': JSON.stringify(process.env.BUILD_COMMIT),
// 'process.env.PORT': JSON.stringify(process.env.PORT),
}),
// generate webpack stats to allow analysis of the bundlesize
new StatsPlugin('webpack.stats.json'),
],
infrastructureLogging: {
level: 'warn', // 'none' | 'error' | 'warn' | 'info' | 'log' | 'verbose'
},
},
css: {
// Enable CSS source maps.
sourceMap: process.env.NODE_ENV !== 'production',
},
outputDir: path.resolve(__dirname, './dist'),
}

13027
admin/yarn.lock Normal file

File diff suppressed because it is too large Load Diff

View File

@ -8,8 +8,6 @@ services:
image: gradido/frontend:development
build:
target: development
networks:
- external-net
environment:
- NODE_ENV="development"
# - DEBUG=true
@ -20,6 +18,23 @@ services:
# bind the local folder to the docker to allow live reload
- ./frontend:/app
########################################################
# ADMIN INTERFACE ######################################
########################################################
admin:
image: gradido/admin:development
build:
target: development
environment:
- NODE_ENV="development"
# - DEBUG=true
volumes:
# This makes sure the docker container has its own node modules.
# Therefore it is possible to have a different node version on the host machine
- admin_node_modules:/app/node_modules
# bind the local folder to the docker to allow live reload
- ./admin:/app
########################################################
# BACKEND ##############################################
########################################################
@ -142,6 +157,7 @@ services:
volumes:
frontend_node_modules:
admin_node_modules:
backend_node_modules:
backend_database_node_modules:
backend_database_build:

View File

@ -15,6 +15,7 @@ services:
context: ./frontend
target: production
networks:
- external-net
- internal-net
ports:
- 3000:3000
@ -30,6 +31,31 @@ services:
# - ./.env
# - ./frontend/.env
########################################################
# ADMIN INTERFACE ######################################
########################################################
admin:
image: gradido/admin:latest
build:
context: ./admin
target: production
networks:
- external-net
- internal-net
ports:
- 8080:8080
environment:
# Envs used in Dockerfile
# - DOCKER_WORKDIR="/app"
# - PORT=8090
# - BUILD_DATE="1970-01-01T00:00:00.00Z"
# - BUILD_VERSION="0.0.0.0"
# - BUILD_COMMIT="0000000"
- NODE_ENV="production"
# env_file:
# - ./.env
# - ./admin/.env
#########################################################
## MARIADB ##############################################
#########################################################

View File

@ -69,7 +69,19 @@ server {
proxy_redirect off;
}
location /sockjs-node {
location /admin {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_pass http://admin:8080;
proxy_redirect off;
}
location /sockjs-node {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';