diff --git a/.env b/.env new file mode 100644 index 00000000..adaedda9 --- /dev/null +++ b/.env @@ -0,0 +1,16 @@ +MYSQL_ROOT_PASSWORD=db>D6~M$4§Y:sChh +MYSQL_USER=aas-server +MYSQL_PASSWORD=60PYRe6Vd8C99u4n + +MONGO_INITDB_ROOT_USERNAME=aas-server +MONGO_INITDB_ROOT_PASSWORD=bObXJWW6e8Nh78YF + +NEXTCLOUD_MYSQL_ROOT_PASSWORD=H68rJ7h4wJ75PgUY +NEXTCLOUD_MYSQL_PASSWORD=VgpnIrk8jJRj435b +NEXTCLOUD_ADMIN_USER=aas-server +NEXTCLOUD_ADMIN_PASSWORD=5w0vmrkzrwDIDyZs +NEXTCLOUD_TRUSTED_DOMAINS=localhost + +AAS_INDEX=mysql://aas-server:60PYRe6Vd8C99u4n@aasportal-index:3306 +USER_STORAGE=mongodb://aas-server:bObXJWW6e8Nh78YF@aasportal-users:27017/aasportal-users +TEMPLATE_STORAGE=http://aas-server:5w0vmrkzrwDIDyZs@aasportal-cloud:8080/templates diff --git a/.gitignore b/.gitignore index 8628dd2f..94d8c3ea 100644 --- a/.gitignore +++ b/.gitignore @@ -42,8 +42,8 @@ temp *-audit.json swagger.json swagger.yaml -projects/aas-server/src/app/routes -./projects/ass-server/src/assets/app-info.json +/projects/aas-server/src/app/routes +/projects/ass-server/src/assets/app-info.json # System files .DS_Store diff --git a/.vscode/launch.json b/.vscode/launch.json index 98442fdb..9fe35daa 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -29,9 +29,9 @@ "CONTENT_ROOT": "projects/aas-server/build", "WEB_ROOT": "projects/aas-portal/dist", "ASSETS": "projects/aas-server/src/assets", - // "USER_STORAGE": "mongodb://172.16.160.177:27017/aasportal-users", - // "TEMPLATE_STORAGE": "http://172.16.160.177:8080/templates", - // "AAS_INDEX": "mysql://172.16.160.177:3306", + "USER_STORAGE": "mongodb://aas-server:bObXJWW6e8Nh78YF@localhost:27017/aasportal-users", + "TEMPLATE_STORAGE": "http://aas-server:5w0vmrkzrwDIDyZs@localhost:8080/templates", + "AAS_INDEX": "mysql://aas-server:60PYRe6Vd8C99u4n@localhost:3306", "ENDPOINTS": "[\"file:///endpoints/samples?name=Samples\"]", } }, diff --git a/Dockerfile b/Dockerfile index d88ea3f1..f10298ff 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,8 +1,7 @@ -# Dockerfile to build server and client parts +# Creates an all-in-one Docker image FROM node:20.11.1-alpine AS build WORKDIR /usr/src/app COPY . . -# RUN apk add g++ make py3-pip RUN npm install RUN node --no-warnings --loader ts-node/esm create-app-info.ts RUN npm run build @@ -10,13 +9,13 @@ RUN npm run build FROM node:20.11.1-alpine AS aasportal RUN apk upgrade --update-cache --available && apk add openssl && rm -rf /var/cache/apk/* WORKDIR /usr/src/app -COPY projects/aas-server/package.json package.json -COPY projects/aas-server/src/assets assets/ +COPY --from=build /usr/src/app/projects/aas-server/package.json package.json RUN npm install --omit=dev -COPY --from=build /usr/src/app/projects/aas-server/dist/ /usr/src/app/ -COPY --from=build /usr/src/app/projects/aas-core/dist/ /usr/src/app/node_modules/aas-core/dist/ -COPY --from=build /usr/src/app/projects/aas-core/package.json /usr/src/app/node_modules/aas-core/package.json -COPY --from=build /usr/src/app/projects/aas-portal/dist/browser/ /usr/src/app/wwwroot/ +COPY --from=build /usr/src/app/projects/aas-server/src/assets assets/ +COPY --from=build /usr/src/app/projects/aas-server/dist/ . +COPY --from=build /usr/src/app/projects/aas-core/dist/ node_modules/aas-core/dist/ +COPY --from=build /usr/src/app/projects/aas-core/package.json node_modules/aas-core/package.json +COPY --from=build /usr/src/app/projects/aas-portal/dist/browser/ wwwroot/ ENV NODE_LOG=./log/debug.log ENV NODE_SERVER_PORT=80 ENV ENDPOINTS=["\"file:///endpoints/samples?name=Samples\""] diff --git a/Dockerfile.aas-portal b/Dockerfile.aas-portal index 421bdaea..85ed471f 100644 --- a/Dockerfile.aas-portal +++ b/Dockerfile.aas-portal @@ -1,9 +1,10 @@ -# Dockerfile to build server and client parts +# Dockerfile to build client app FROM node:20.11.1-alpine AS build WORKDIR /usr/src/app COPY . . RUN npm install RUN npm run aas-portal:build + FROM nginx:latest AS aas-portal #possibility to check host & port availability of other containers via netcat RUN apt-get update -y && apt-get install -y netcat-openbsd diff --git a/Dockerfile.aas-server b/Dockerfile.aas-server index 406c7f43..c6c4d282 100644 --- a/Dockerfile.aas-server +++ b/Dockerfile.aas-server @@ -1,8 +1,7 @@ -# Dockerfile to build server and client parts -FROM node:20.11.1-alpine as build +# Dockerfile to build server app +FROM node:20.11.1-alpine AS build WORKDIR /usr/src/app COPY . . -# RUN apk add g++ make py3-pip RUN npm install RUN node --no-warnings --loader ts-node/esm create-app-info.ts RUN npm run aas-server:build @@ -10,19 +9,17 @@ RUN npm run aas-server:build FROM node:20.11.1-alpine AS aas-server RUN apk upgrade --update-cache --available && apk add openssl && rm -rf /var/cache/apk/* WORKDIR /usr/src/app -COPY projects/aas-server/package.json package.json -COPY projects/aas-server/src/assets assets/ +COPY --from=build /usr/src/app/projects/aas-server/package.json package.json RUN npm install --omit=dev -COPY --from=build /usr/src/app/projects/aas-server/dist/ /usr/src/app/ -COPY --from=build /usr/src/app/projects/aas-core/dist/ /usr/src/app/node_modules/aas-core/dist/ -COPY --from=build /usr/src/app/projects/aas-core/package.json /usr/src/app/node_modules/aas-core/package.json +COPY --from=build /usr/src/app/projects/aas-server/src/assets assets/ +COPY --from=build /usr/src/app/projects/aas-server/dist/ . +COPY --from=build /usr/src/app/projects/aas-core/dist/ node_modules/aas-core/dist/ +COPY --from=build /usr/src/app/projects/aas-core/package.json node_modules/aas-core/package.json ENV NODE_LOG=./log/debug.log ENV NODE_SERVER_PORT=1337 -ENV USER_STORAGE=mongodb://172.16.160.177:27017/aasportal-users -ENV AAS_INDEX=mysql://172.16.160.177:3306 -ENV TEMPLATE_STORAGE: http://172.16.160.177:8080/templates ENV ENDPOINTS=["\"file:///endpoints/samples?name=Samples\""] ENV NODE_ENV=production EXPOSE 1337 CMD ["node", "aas-server.js" ] + \ No newline at end of file diff --git a/create-app-info.ts b/create-app-info.ts index d828ffc0..d981b36b 100644 --- a/create-app-info.ts +++ b/create-app-info.ts @@ -9,7 +9,7 @@ import { readFile, writeFile, readdir } from 'fs/promises'; import path from 'path'; import { existsSync } from 'fs'; -import { dirname, resolve, join } from 'path'; +import { dirname, join } from 'path'; import { fileURLToPath } from 'url'; interface Package { @@ -65,7 +65,16 @@ const exclude = new Set(['aas-core', 'aas-lib', 'aas-portal', 'aas-server', 'fhg await main(); async function main(): Promise { - const project: Package = await read(resolve(__dirname, 'package.json')); + const packageFile = join(__dirname, 'package.json'); + let project: Package; + try { + project = await JSON.parse((await readFile(packageFile)).toString()); + console.info(`File ${packageFile} read.`); + } catch (error) { + console.error(error); + return; + } + const appInfo: ApplicationInfo = { name: project.name, version: project.version, @@ -76,16 +85,13 @@ async function main(): Promise { libraries: await readLibrariesAsync(project), }; - const file = resolve(__dirname, 'projects/aas-server/src/assets/app-info.json'); - await write(file, appInfo); -} - -async function read(file: string): Promise { - return JSON.parse((await readFile(file)).toString()); -} - -function write(file: string, data: object): Promise { - return writeFile(file, JSON.stringify(data, undefined, 2)); + const file = join(__dirname, 'projects/aas-server/src/assets/app-info.json'); + try { + await writeFile(file, JSON.stringify(appInfo, undefined, 2)); + console.info(`File ${file} read.`); + } catch (error) { + console.error(error); + } } async function readLibrariesAsync(project: Package): Promise { diff --git a/docker-compose.yml b/docker-compose.yml index 20d4a866..734e2ca6 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -6,15 +6,14 @@ services: ports: - 27017:27017 volumes: - #persist db data (users remain after restart) - mongodata:/data/db environment: - - MONGO_INITDB_ROOT_USERNAME=aas-server - - MONGO_INITDB_ROOT_PASSWORD=aas-server + - MONGO_INITDB_ROOT_USERNAME=${MONGO_INITDB_ROOT_USERNAME} + - MONGO_INITDB_ROOT_PASSWORD=${MONGO_INITDB_ROOT_PASSWORD} - MONGO_INITDB_DATABASE=aasportal-users aasportal-index: - image: mariadb:latest + image: mariadb container_name: aasportal-index command: --default-authentication-plugin=mysql_native_password healthcheck: @@ -34,20 +33,56 @@ services: - sqldata:/var/lib/mysql restart: always environment: - MYSQL_ROOT_PASSWORD: db>D6~M$4§Y:sChh + MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD} MYSQL_DATABASE: aas-index - MYSQL_USER: aas-server - MYSQL_PASSWORD: aas-server + MYSQL_USER: ${MYSQL_USER} + MYSQL_PASSWORD: ${MYSQL_PASSWORD} ports: - 3306:3306 + aasportal-cloud-db: + image: mariadb + container_name: aasportal-cloud-db + restart: always + command: --transaction-isolation=READ-COMMITTED --log-bin=binlog --binlog-format=ROW + volumes: + - nextcloud_db:/var/lib/mysql + environment: + - MYSQL_ROOT_PASSWORD=${NEXTCLOUD_MYSQL_ROOT_PASSWORD} + - MYSQL_PASSWORD=${NEXTCLOUD_PASSWORD} + - MYSQL_DATABASE=nextcloud + - MYSQL_USER=nextcloud + + aasportal-cloud: + image: nextcloud + container_name: aasportal-cloud + restart: always + ports: + - 8080:80 + links: + - aasportal-cloud-db + volumes: + - nextcloud:/var/www/html + environment: + - MYSQL_PASSWORD=${NEXTCLOUD_MYSQL_PASSWORD} + - MYSQL_DATABASE=nextcloud + - MYSQL_USER=nextcloud + - MYSQL_HOST=aasportal-cloud-db + - NEXTCLOUD_ADMIN_USER=${NEXTCLOUD_ADMIN_USER} + - NEXTCLOUD_ADMIN_PASSWORD=${NEXTCLOUD_ADMIN_PASSWORD} + - NEXTCLOUD_TRUSTED_DOMAINS=${NEXTCLOUD_TRUSTED_DOMAINS} + aas-server: container_name: aas-server build: context: . dockerfile: ./Dockerfile.aas-server environment: - - USER_STORAGE=mongodb://aasportal-users:27017/aasportal-users + - USER_STORAGE=${USER_STORAGE} + - AAS_INDEX=${AAS_INDEX} + - TEMPLATE_STORAGE=${TEMPLATE_STORAGE} + ports: + - 1337:1337 aas-portal: container_name: aas-portal @@ -57,6 +92,9 @@ services: restart: always ports: - 80:80 + volumes: mongodata: - sqldata: \ No newline at end of file + sqldata: + nextcloud_db: + nextcloud: \ No newline at end of file diff --git a/package.json b/package.json index f2714660..e7e1d631 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "aas-portal-project", "version": "3.0.0-development.94", - "description": "Web-based visualization and control of aaset administration shells.", + "description": "Web-based visualization and control of asset administration shells.", "type": "module", "scripts": { "create-app-info": "node --no-warnings --loader ts-node/esm create-app-info.ts", diff --git a/projects/aas-lib/src/test/aas-tree/aas-tree-search.spec.ts b/projects/aas-lib/src/test/aas-tree/aas-tree-search.spec.ts index 790a8dbd..9570e7ed 100644 --- a/projects/aas-lib/src/test/aas-tree/aas-tree-search.spec.ts +++ b/projects/aas-lib/src/test/aas-tree/aas-tree-search.spec.ts @@ -11,7 +11,7 @@ import { TranslateFakeLoader, TranslateLoader, TranslateModule, TranslateService import { AASTreeSearch } from '../../lib/aas-tree/aas-tree-search'; import { sampleDocument } from '../assets/sample-document'; import { AASTreeService } from '../../lib/aas-tree/aas-tree.service'; -import { NotifyService } from 'projects/aas-lib/dist'; +import { NotifyService } from '../../lib/notify/notify.service'; describe('AASTreeSearch', function () { let search: AASTreeSearch; diff --git a/projects/aas-server/src/app/aas-index/aas-index-factory.ts b/projects/aas-server/src/app/aas-index/aas-index-factory.ts index adb5ec46..2bf1cd7f 100644 --- a/projects/aas-server/src/app/aas-index/aas-index-factory.ts +++ b/projects/aas-server/src/app/aas-index/aas-index-factory.ts @@ -15,23 +15,34 @@ import { LowDbIndex } from './lowdb/lowdb-index.js'; import { Variable } from '../variable.js'; import { LowDbData } from './lowdb/lowdb-types.js'; import { MySqlIndex } from './mysql/mysql-index.js'; +import { Logger } from '../logging/logger.js'; +import { urlToString } from '../convert.js'; export class AASIndexFactory { public constructor(private readonly container: DependencyContainer) {} public create(): AASIndex { const variable = this.container.resolve(Variable); + const logger = this.container.resolve('Logger'); if (variable.AAS_INDEX) { - const url = new URL(variable.AAS_INDEX); - if (url.protocol === 'mysql:') { - return new MySqlIndex(variable); - } + try { + const url = new URL(variable.AAS_INDEX); + if (url.protocol === 'mysql:') { + const index = new MySqlIndex(variable); + logger.info(`AAS index connected to ${urlToString(url)}.`); + return index; + } - throw new Error('Not implemented.'); + throw new Error(`${urlToString(url)} is a not supported AAS index.`); + } catch (error) { + logger.error(error); + } } const dbFile = path.join(variable.CONTENT_ROOT, 'db.json'); const db = new Low(new JSONFile(dbFile), { documents: [], endpoints: [], elements: [] }); - return new LowDbIndex(db, variable); + const index = new LowDbIndex(db, variable); + logger.info('Using internal AAS index.'); + return index; } } diff --git a/projects/aas-server/src/app/auth/mongo-db-user-storage.ts b/projects/aas-server/src/app/auth/mongo-db-user-storage.ts index af953114..7f8cf932 100644 --- a/projects/aas-server/src/app/auth/mongo-db-user-storage.ts +++ b/projects/aas-server/src/app/auth/mongo-db-user-storage.ts @@ -21,7 +21,7 @@ export interface UserCookies { @injectable() export class MongoDBUserStorage extends UserStorage { - private connected?: Mongoose; + private connected: Promise; private readonly userDataSchema = new Schema({ id: { type: String, required: true }, @@ -48,20 +48,22 @@ export class MongoDBUserStorage extends UserStorage { public constructor(@inject(Variable) private readonly variable: Variable) { super(); + + this.connected = this.connect(); } public async existAsync(userId: string): Promise { - await this.ensureConnected(); + await this.connected; return (await this.userModel.findOne({ id: userId }).exec()) != null; } public async readAsync(userId: string): Promise { - await this.ensureConnected(); + await this.connected; return (await this.userModel.findOne({ id: userId }).exec()) ?? undefined; } public async writeAsync(userId: string, data: UserData): Promise { - await this.ensureConnected(); + await this.connected; let instance = await this.userModel.findOne({ id: userId }).exec(); if (instance) { instance.name = data.name; @@ -75,12 +77,12 @@ export class MongoDBUserStorage extends UserStorage { } public async deleteAsync(userId: string): Promise { - await this.ensureConnected(); + await this.connected; return (await this.userModel.findOneAndDelete({ id: userId }).exec()) != null; } public async checkCookieAsync(userId: string, name: string): Promise { - await this.ensureConnected(); + await this.connected; const user = await this.cookieModel.findOne({ id: userId }).exec(); if (user != null) { return user.cookies.some(cookie => cookie.name === name); @@ -90,7 +92,7 @@ export class MongoDBUserStorage extends UserStorage { } public async getCookieAsync(userId: string, name: string): Promise { - await this.ensureConnected(); + await this.connected; const user = await this.cookieModel.findOne({ id: userId }).exec(); if (user != null) { return user.cookies.find(cookie => cookie.name === name); @@ -100,7 +102,7 @@ export class MongoDBUserStorage extends UserStorage { } public async getCookiesAsync(userId: string): Promise { - await this.ensureConnected(); + await this.connected; const user = await this.cookieModel.findOne({ id: userId }).exec(); if (user != null) { return user.cookies; @@ -110,7 +112,7 @@ export class MongoDBUserStorage extends UserStorage { } public async setCookieAsync(userId: string, name: string, data: string): Promise { - await this.ensureConnected(); + await this.connected; let user = await this.cookieModel.findOne({ id: userId }).exec(); if (user) { const index = user.cookies.findIndex(cookie => cookie.name === name); @@ -127,7 +129,7 @@ export class MongoDBUserStorage extends UserStorage { } public async deleteCookieAsync(userId: string, name: string): Promise { - await this.ensureConnected(); + await this.connected; const user = await this.cookieModel.findOne({ id: userId }).exec(); if (user) { const index = user.cookies.findIndex(cookie => cookie.name === name); @@ -142,20 +144,18 @@ export class MongoDBUserStorage extends UserStorage { } } - private async ensureConnected(): Promise { - if (!this.connected) { - const url = new URL(this.variable.USER_STORAGE!); - const username = isEmpty(url.username) ? this.variable.AAS_SERVER_USERNAME : url.username; - const password = isEmpty(url.password) ? this.variable.AAS_SERVER_PASSWORD : url.pathname; - const dbName = isEmpty(url.pathname) ? 'aasportal-users' : url.pathname.substring(1); - url.username = ''; - url.password = ''; - url.pathname = ''; - this.connected = await mongoose.connect(url.href, { - dbName: dbName, - user: username, - pass: password, - }); - } + private connect(): Promise { + const url = new URL(this.variable.USER_STORAGE!); + const username = isEmpty(url.username) ? this.variable.AAS_SERVER_USERNAME : url.username; + const password = isEmpty(url.password) ? this.variable.AAS_SERVER_PASSWORD : url.password; + const dbName = isEmpty(url.pathname) ? 'aasportal-users' : url.pathname.substring(1); + url.username = ''; + url.password = ''; + url.pathname = ''; + return mongoose.connect(url.href, { + dbName: dbName, + user: username, + pass: password, + }); } } diff --git a/projects/aas-server/src/app/auth/user-storage-factory.ts b/projects/aas-server/src/app/auth/user-storage-factory.ts index e902f1ad..2a1dfd1d 100644 --- a/projects/aas-server/src/app/auth/user-storage-factory.ts +++ b/projects/aas-server/src/app/auth/user-storage-factory.ts @@ -12,6 +12,7 @@ import { LocalUserStorage } from './local-user-storage.js'; import { Variable } from '../variable.js'; import { MongoDBUserStorage } from './mongo-db-user-storage.js'; import { Logger } from '../logging/logger.js'; +import { urlToString } from '../convert.js'; /* istanbul ignore next */ export class UserStorageFactory { @@ -22,12 +23,13 @@ export class UserStorageFactory { const logger = this.container.resolve('Logger'); if (url) { try { - if (new URL(url).protocol === 'mongodb:') { + const protocol = new URL(url).protocol; + if (protocol === 'mongodb:') { const storage = this.container.resolve(MongoDBUserStorage); - logger.info(`Using user storage at: ${url}`); + logger.info(`User storage connected to "${urlToString(url)}".`); return storage; } else { - throw new Error(`"${url}" is a not supported user storage.`); + throw new Error(`"${urlToString(url)}" is a not supported user storage.`); } } catch (error) { logger.error(error); @@ -35,7 +37,7 @@ export class UserStorageFactory { } const storage = this.container.resolve(LocalUserStorage); - logger.info(`Using local user storage.`); + logger.info(`Using internal user storage.`); return storage; } } diff --git a/projects/aas-server/src/app/convert.ts b/projects/aas-server/src/app/convert.ts index c6877712..7695afd1 100644 --- a/projects/aas-server/src/app/convert.ts +++ b/projects/aas-server/src/app/convert.ts @@ -30,6 +30,13 @@ export function parseUrl(url: string): URL { } } +export function urlToString(url: URL | string): string { + const temp = new URL(url); + temp.password = ''; + temp.username = ''; + return temp.toString(); +} + export function toUint8Array(data: T): Uint8Array { return Uint8Array.from(Buffer.from(JSON.stringify(data))); } diff --git a/projects/aas-server/src/app/file-storage/file-storage-provider.ts b/projects/aas-server/src/app/file-storage/file-storage-provider.ts index d043819a..c6745bee 100644 --- a/projects/aas-server/src/app/file-storage/file-storage-provider.ts +++ b/projects/aas-server/src/app/file-storage/file-storage-provider.ts @@ -12,12 +12,17 @@ import { FileStorage } from './file-storage.js'; import { LocalFileStorage } from './local-file-storage.js'; import { Variable } from '../variable.js'; import { WebDAVStorage } from './webdav-storage.js'; +import { Logger } from '../logging/logger.js'; +import { urlToString } from '../convert.js'; @singleton() export class FileStorageProvider { private readonly instances = new Map(); - public constructor(@inject(Variable) private readonly variable: Variable) {} + public constructor( + @inject(Variable) private readonly variable: Variable, + @inject('Logger') private readonly logger: Logger, + ) {} /** * Gets a FileStorage for the specified URL. @@ -25,12 +30,13 @@ export class FileStorageProvider { * @returns A FileStorage instance. */ public get(url: string | URL | undefined = 'file:///'): FileStorage { - url = typeof url === 'string' ? new URL(url) : url; + url = new URL(url); const key = url.protocol + '//' + url.host; let instance = this.instances.get(key); if (!instance) { instance = this.create(url); this.instances.set(key, instance); + this.logger.info(`File storage "${key}" registered.`); } return instance; @@ -39,8 +45,9 @@ export class FileStorageProvider { private create(url: URL): FileStorage { url = new URL(url); switch (url.protocol) { - case 'file:': + case 'file:': { return new LocalFileStorage(url.href, this.variable.ASSETS); + } case 'http:': case 'https:': if (isEmpty(url.username)) { @@ -52,10 +59,9 @@ export class FileStorageProvider { } url.pathname = ''; - return new WebDAVStorage(url); default: - throw new Error(`${url.href} is an invalid URL or a not supported file storage.`); + throw new Error(`"${urlToString(url)}" is a not supported file storage.`); } } } diff --git a/projects/aas-server/src/app/file-storage/webdav-storage.ts b/projects/aas-server/src/app/file-storage/webdav-storage.ts index d6537c97..d17b4513 100644 --- a/projects/aas-server/src/app/file-storage/webdav-storage.ts +++ b/projects/aas-server/src/app/file-storage/webdav-storage.ts @@ -11,14 +11,14 @@ import { dirname, join, normalize, relative, sep } from 'path/posix'; import { FileStorage, FileStorageEntry } from './file-storage.js'; export class WebDAVStorage extends FileStorage { - public constructor( - url: string | URL, - private _client?: WebDAVClient, - ) { + private client: WebDAVClient; + + public constructor(url: string | URL, client?: WebDAVClient) { url = typeof url === 'string' ? new URL(url) : url; super(sep); this.url = typeof url === 'string' ? url : url.href; + this.client = client || this.createClient(); } public override readonly url: string; @@ -66,22 +66,18 @@ export class WebDAVStorage extends FileStorage { return this.client.createReadStream(this.resolve(path)); } - private get client(): WebDAVClient { - if (!this._client) { - const url = new URL(this.url); - url.pathname = '/remote.php/webdav'; - const username = url.username; - const password = url.password; - url.username = ''; - url.password = ''; - - this._client = createClient(url.href, { - username: username, - password: password, - }); - } - - return this._client; + private createClient(): WebDAVClient { + const url = new URL(this.url); + url.pathname = '/remote.php/webdav'; + const username = url.username; + const password = url.password; + url.username = ''; + url.password = ''; + + return createClient(url.href, { + username: username, + password: password, + }); } private resolve(path: string): string { diff --git a/projects/aas-server/src/assets/app-info.json b/projects/aas-server/src/assets/app-info.json index d8c2240b..feb94024 100644 --- a/projects/aas-server/src/assets/app-info.json +++ b/projects/aas-server/src/assets/app-info.json @@ -1,7 +1,7 @@ { "name": "aas-portal-project", "version": "3.0.0-development.94", - "description": "Web-based visualization and control of aaset administration shells.", + "description": "Web-based visualization and control of asset administration shells.", "author": "Fraunhofer IOSB-INA", "homepage": "https://www.iosb-ina.fraunhofer.de/", "license": "Apache-2.0", @@ -93,13 +93,6 @@ "license": "MIT", "licenseText": "The MIT License\n\nCopyright (c) 2010-2024 Google LLC. https://angular.io/license\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n" }, - { - "name": "@angular/elements", - "version": "18.2.4", - "description": "Angular - library for using Angular Components as Custom Elements", - "license": "MIT", - "licenseText": "" - }, { "name": "@angular/forms", "version": "18.2.4", diff --git a/projects/aasportal-cloud/.env b/projects/aasportal-cloud/.env index 24cf9916..729b04e4 100644 --- a/projects/aasportal-cloud/.env +++ b/projects/aasportal-cloud/.env @@ -1,6 +1,5 @@ -HTTP_PORT=8080 -MYSQL_ROOT_PASSWORD=djtg&Usx9Cx$fD5v -MYSQL_PASSWORD=aas-server +NEXTCLOUD_MYSQL_ROOT_PASSWORD=H68rJ7h4wJ75PgUY +NEXTCLOUD_MYSQL_PASSWORD=VgpnIrk8jJRj435b NEXTCLOUD_ADMIN_USER=aas-server -NEXTCLOUD_ADMIN_PASSWORD=aas-server +NEXTCLOUD_ADMIN_PASSWORD=5w0vmrkzrwDIDyZs NEXTCLOUD_TRUSTED_DOMAINS=localhost \ No newline at end of file diff --git a/projects/aasportal-cloud/docker-compose.yml b/projects/aasportal-cloud/docker-compose.yml index 64c8310d..7fa40a20 100644 --- a/projects/aasportal-cloud/docker-compose.yml +++ b/projects/aasportal-cloud/docker-compose.yml @@ -1,38 +1,36 @@ -version: '2' - volumes: nextcloud: - db: + nextcloud_db: services: - db: + aasportal-cloud-db: image: mariadb - container_name: nextcloud_db + container_name: aasportal-cloud-db restart: always command: --transaction-isolation=READ-COMMITTED --log-bin=binlog --binlog-format=ROW volumes: - - db:/var/lib/mysql + - nextcloud_db:/var/lib/mysql environment: - - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD} - - MYSQL_PASSWORD=${MYSQL_PASSWORD} + - MYSQL_ROOT_PASSWORD=${NEXTCLOUD_MYSQL_ROOT_PASSWORD} + - MYSQL_PASSWORD=${NEXTCLOUD_MYSQL_PASSWORD} - MYSQL_DATABASE=nextcloud - MYSQL_USER=nextcloud - app: + aasportal-cloud-app: image: nextcloud - container_name: nextcloud_server + container_name: aasportal-cloud-app restart: always ports: - - ${HTTP_PORT}:80 + - 8080:80 links: - - db + - aasportal-cloud-db volumes: - nextcloud:/var/www/html environment: - - MYSQL_PASSWORD=aas-server + - MYSQL_PASSWORD=${NEXTCLOUD_MYSQL_PASSWORD} - MYSQL_DATABASE=nextcloud - MYSQL_USER=nextcloud - - MYSQL_HOST=db + - MYSQL_HOST=aasportal-cloud-db - NEXTCLOUD_ADMIN_USER=${NEXTCLOUD_ADMIN_USER} - NEXTCLOUD_ADMIN_PASSWORD=${NEXTCLOUD_ADMIN_PASSWORD} - NEXTCLOUD_TRUSTED_DOMAINS=${NEXTCLOUD_TRUSTED_DOMAINS} \ No newline at end of file diff --git a/projects/aasportal-index/.env b/projects/aasportal-index/.env index 67a44bbb..386ab7c1 100644 --- a/projects/aasportal-index/.env +++ b/projects/aasportal-index/.env @@ -1,4 +1,3 @@ MYSQL_ROOT_PASSWORD=db>D6~M$4§Y:sChh -MYSQL_DATABASE=aas-index MYSQL_USER=aas-server -MYSQL_PASSWORD=aas-server \ No newline at end of file +MYSQL_PASSWORD=60PYRe6Vd8C99u4n \ No newline at end of file diff --git a/projects/aasportal-index/docker-compose.yml b/projects/aasportal-index/docker-compose.yml index a2c3ef36..c5cf74c3 100644 --- a/projects/aasportal-index/docker-compose.yml +++ b/projects/aasportal-index/docker-compose.yml @@ -1,18 +1,20 @@ -version: "3.9" services: - mysql: - image: mariadb:latest + aasportal-index: + image: mariadb container_name: aasportal-index command: --default-authentication-plugin=mysql_native_password volumes: - ./schema.sql:/docker-entrypoint-initdb.d/1.sql - - /var/lib/mysql + - sqldata:/var/lib/mysql restart: always environment: MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD} - MYSQL_DATABASE: ${MYSQL_DATABASE} + MYSQL_DATABASE: aas-index MYSQL_USER: ${MYSQL_USER} MYSQL_PASSWORD: ${MYSQL_PASSWORD} ports: - - 3306:3306 \ No newline at end of file + - 3306:3306 + +volumes: + sqldata: \ No newline at end of file diff --git a/projects/aasportal-users/.env b/projects/aasportal-users/.env index d5be0129..9d36ba39 100644 --- a/projects/aasportal-users/.env +++ b/projects/aasportal-users/.env @@ -1,2 +1,2 @@ MONGO_INITDB_ROOT_USERNAME=aas-server -MONGO_INITDB_ROOT_PASSWORD=aas-server +MONGO_INITDB_ROOT_PASSWORD=bObXJWW6e8Nh78YF diff --git a/projects/aasportal-users/docker-compose.yml b/projects/aasportal-users/docker-compose.yml index 5b7205be..669a0b40 100644 --- a/projects/aasportal-users/docker-compose.yml +++ b/projects/aasportal-users/docker-compose.yml @@ -1,5 +1,3 @@ -version: "3" - services: mongo: image: mongo @@ -8,7 +6,11 @@ services: ports: - 27017:27017 volumes: - - /data/db + - mongodata:/data/db environment: - MONGO_INITDB_ROOT_USERNAME=${MONGO_INITDB_ROOT_USERNAME} - MONGO_INITDB_ROOT_PASSWORD=${MONGO_INITDB_ROOT_PASSWORD} + - MONGO_INITDB_DATABASE=aasportal-users + +volumes: + mongodata: \ No newline at end of file