diff --git a/back/Dockerfile b/back/Dockerfile index 56a74d39..55f36c87 100644 --- a/back/Dockerfile +++ b/back/Dockerfile @@ -1,5 +1,9 @@ +# The building of ProtoBuf "messages" must be done out of Docker because grpc-node does not ship with ARM64 binaries. +# See: https://github.com/grpc/grpc-node/issues/1405 +# When the issue above is closed, we can move back messages building inside Dockerfile + # protobuf build -FROM node:14.18.2-buster-slim@sha256:20bedf0c09de887379e59a41c04284974f5fb529cf0e13aab613473ce298da3d as messages +FROM node:1.18.2-buster-slim@sha256:20bedf0c09de887379e59a41c04284974f5fb529cf0e13aab613473ce298da3d as proto-builder WORKDIR /usr/src COPY messages/yarn.lock messages/package.json ./ RUN yarn install @@ -7,17 +11,17 @@ COPY messages . RUN yarn proto # typescript build -FROM node:14.18.2-buster-slim@sha256:20bedf0c09de887379e59a41c04284974f5fb529cf0e13aab613473ce298da3d as builder +FROM node:16.15-buster-slim@sha256:9ad2f889d4a15ef94e40ac75e95c28daa34073dbc25d7b1e619caacc6b83623c as builder WORKDIR /usr/src COPY back/yarn.lock back/package.json ./ RUN yarn install COPY back . -COPY --from=messages /usr/src/generated src/Messages/generated +COPY --from=proto-builder /usr/src/generated src/Messages/generated ENV NODE_ENV=production RUN yarn run tsc # final production image -FROM node:14.18.2-buster-slim@sha256:20bedf0c09de887379e59a41c04284974f5fb529cf0e13aab613473ce298da3d +FROM node:16.15-buster-slim@sha256:9ad2f889d4a15ef94e40ac75e95c28daa34073dbc25d7b1e619caacc6b83623c WORKDIR /usr/src COPY back/yarn.lock back/package.json ./ ENV NODE_ENV=production diff --git a/back/package.json b/back/package.json index eee46b56..401716d4 100644 --- a/back/package.json +++ b/back/package.json @@ -55,7 +55,7 @@ "prom-client": "^12.0.0", "query-string": "^6.13.3", "redis": "^3.1.2", - "uWebSockets.js": "uNetworking/uWebSockets.js#v18.5.0", + "uWebSockets.js": "uNetworking/uWebSockets.js#v20.10.0", "uuidv4": "^6.0.7", "zod": "^3.14.3" }, @@ -65,7 +65,7 @@ "@types/debug": "^4.1.5", "@types/google-protobuf": "^3.7.3", "@types/http-status-codes": "^1.2.0", - "@types/jasmine": "^3.5.10", + "@types/jasmine": "^4.0.3", "@types/jsonwebtoken": "^8.3.8", "@types/mkdirp": "^1.0.1", "@types/redis": "^2.8.31", @@ -73,7 +73,7 @@ "@typescript-eslint/eslint-plugin": "^5.8.0", "@typescript-eslint/parser": "^5.8.0", "eslint": "^8.5.0", - "jasmine": "^3.5.0", + "jasmine": "^4.0.3", "lint-staged": "^11.0.0", "prettier": "^2.3.1", "ts-node-dev": "^1.1.8", diff --git a/back/yarn.lock b/back/yarn.lock index 615d7794..c3efbc10 100644 --- a/back/yarn.lock +++ b/back/yarn.lock @@ -135,10 +135,10 @@ dependencies: http-status-codes "*" -"@types/jasmine@^3.5.10": - version "3.10.2" - resolved "https://registry.yarnpkg.com/@types/jasmine/-/jasmine-3.10.2.tgz#1b9f9ba9ad7bfd7d322f7ed9d8753220b1c84b52" - integrity sha512-qs4xjVm4V/XjM6owGm/x6TNmhGl5iKX8dkTdsgdgl9oFnqgzxLepnS7rN9Tdo7kDmnFD/VEqKrW57cGD2odbEg== +"@types/jasmine@^4.0.3": + version "4.0.3" + resolved "https://registry.yarnpkg.com/@types/jasmine/-/jasmine-4.0.3.tgz#097ce710d70eb7f3662e96c1f75824dd22c27d5c" + integrity sha512-Opp1LvvEuZdk8fSSvchK2mZwhVrsNT0JgJE9Di6MjnaIpmEXM8TLCPPrVtNTYh8+5MPdY8j9bAHMu2SSfwpZJg== "@types/json-schema@^7.0.9": version "7.0.9" @@ -1225,18 +1225,18 @@ isexe@^2.0.0: resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= -jasmine-core@~3.10.0: - version "3.10.1" - resolved "https://registry.yarnpkg.com/jasmine-core/-/jasmine-core-3.10.1.tgz#7aa6fa2b834a522315c651a128d940eca553989a" - integrity sha512-ooZWSDVAdh79Rrj4/nnfklL3NQVra0BcuhcuWoAwwi+znLDoUeH87AFfeX8s+YeYi6xlv5nveRyaA1v7CintfA== +jasmine-core@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/jasmine-core/-/jasmine-core-4.1.0.tgz#2377349b0e8bfd3fbdb36c9e4f09e3b1a17cf5c2" + integrity sha512-8E8BiffCL8sBwK1zU9cbavLe8xpJAgOduSJ6N8PJVv8VosQ/nxVTuXj2kUeHxTlZBVvh24G19ga7xdiaxlceKg== -jasmine@^3.5.0: - version "3.10.0" - resolved "https://registry.yarnpkg.com/jasmine/-/jasmine-3.10.0.tgz#acd3cd560a9d20d8fdad6bd2dd05867d188503f3" - integrity sha512-2Y42VsC+3CQCTzTwJezOvji4qLORmKIE0kwowWC+934Krn6ZXNQYljiwK5st9V3PVx96BSiDYXSB60VVah3IlQ== +jasmine@^4.0.3: + version "4.1.0" + resolved "https://registry.yarnpkg.com/jasmine/-/jasmine-4.1.0.tgz#0de347ca8bb6cc764b0ed186ae4cfc45bd64bdc4" + integrity sha512-4VhjbUgwfNS9CBnUMoSWr9tdNgOoOhNIjAD8YRxTn+PmOf4qTSC0Uqhk66dWGnz2vJxtNIU0uBjiwnsp4Ud9VA== dependencies: glob "^7.1.6" - jasmine-core "~3.10.0" + jasmine-core "^4.1.0" js-tokens@^4.0.0: version "4.0.0" @@ -2139,9 +2139,9 @@ typescript@^4.5.4: resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.5.4.tgz#a17d3a0263bf5c8723b9c52f43c5084edf13c2e8" integrity sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg== -uWebSockets.js@uNetworking/uWebSockets.js#v18.5.0: - version "18.5.0" - resolved "https://codeload.github.com/uNetworking/uWebSockets.js/tar.gz/9b1605d2db82981cafe69dbe356e10ce412f5805" +uWebSockets.js@uNetworking/uWebSockets.js#v20.10.0: + version "20.10.0" + resolved "https://codeload.github.com/uNetworking/uWebSockets.js/tar.gz/806df48c9da86af7b3341f3e443388c7cd15c3de" uri-js@^4.2.2: version "4.4.1" diff --git a/docker-compose.single-domain.yaml b/docker-compose.single-domain.yaml index b9149ba0..fd71a9f8 100644 --- a/docker-compose.single-domain.yaml +++ b/docker-compose.single-domain.yaml @@ -19,7 +19,7 @@ services: - /var/run/docker.sock:/var/run/docker.sock front: - image: thecodingmachine/nodejs:14 + image: thecodingmachine/nodejs:16 environment: DEBUG_MODE: "$DEBUG_MODE" JITSI_URL: $JITSI_URL @@ -55,7 +55,7 @@ services: - "traefik.http.routers.front-ssl.service=front" pusher: - image: thecodingmachine/nodejs:14 + image: thecodingmachine/nodejs:16 command: yarn dev #command: yarn run prod #command: yarn run profile @@ -122,7 +122,7 @@ services: - "traefik.http.routers.maps-ssl.service=maps" back: - image: thecodingmachine/nodejs:12 + image: thecodingmachine/nodejs:16 command: yarn dev #command: yarn run profile environment: @@ -154,7 +154,7 @@ services: - "traefik.http.routers.back-ssl.service=back" uploader: - image: thecodingmachine/nodejs:12 + image: thecodingmachine/nodejs:16 command: yarn dev #command: yarn run profile environment: @@ -175,7 +175,6 @@ services: - "traefik.http.routers.uploader-ssl.service=uploader" messages: - #image: thecodingmachine/nodejs:14 image: thecodingmachine/workadventure-back-base:latest environment: #STARTUP_COMMAND_0: sudo apt-get install -y inotify-tools diff --git a/docker-compose.yaml b/docker-compose.yaml index 230cf632..f4f3acdf 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -26,7 +26,7 @@ services: - 'maps.workadventure.localhost' front: - image: thecodingmachine/nodejs:14 + image: thecodingmachine/nodejs:16 environment: DEBUG_MODE: "$DEBUG_MODE" JITSI_URL: $JITSI_URL @@ -66,7 +66,7 @@ services: - "traefik.http.routers.front-ssl.service=front" pusher: - image: thecodingmachine/nodejs:14 + image: thecodingmachine/nodejs:16 command: yarn dev environment: DEBUG: "socket:*" @@ -127,7 +127,7 @@ services: - "traefik.http.routers.maps-ssl.service=maps" back: - image: thecodingmachine/nodejs:12 + image: thecodingmachine/nodejs:16 command: yarn dev #command: yarn run profile environment: @@ -159,7 +159,7 @@ services: - "traefik.http.routers.back-ssl.service=back" uploader: - image: thecodingmachine/nodejs:12 + image: thecodingmachine/nodejs:16 command: yarn dev #command: yarn run profile environment: @@ -178,7 +178,6 @@ services: - "traefik.http.routers.uploader-ssl.service=uploader" messages: - #image: thecodingmachine/nodejs:14 image: thecodingmachine/workadventure-back-base:latest environment: #STARTUP_COMMAND_0: sudo apt-get install -y inotify-tools diff --git a/front/Dockerfile b/front/Dockerfile index 299f9260..6eab915d 100644 --- a/front/Dockerfile +++ b/front/Dockerfile @@ -1,5 +1,9 @@ +# The building of ProtoBuf "messages" must be done out of Docker because grpc-node does not ship with ARM64 binaries. +# See: https://github.com/grpc/grpc-node/issues/1405 +# When the issue above is closed, we can move back messages building inside Dockerfile + # protobuf build -FROM node:14.18.2-buster-slim@sha256:20bedf0c09de887379e59a41c04284974f5fb529cf0e13aab613473ce298da3d as messages +FROM node:1.18.2-buster-slim@sha256:20bedf0c09de887379e59a41c04284974f5fb529cf0e13aab613473ce298da3d as proto-builder WORKDIR /usr/src COPY messages/yarn.lock messages/package.json ./ RUN yarn install @@ -7,21 +11,23 @@ COPY messages . RUN yarn ts-proto # typescript build -FROM node:14.18.2-buster-slim@sha256:20bedf0c09de887379e59a41c04284974f5fb529cf0e13aab613473ce298da3d as builder +FROM node:16.15-buster-slim@sha256:9ad2f889d4a15ef94e40ac75e95c28daa34073dbc25d7b1e619caacc6b83623c as builder WORKDIR /usr/src COPY front/yarn.lock front/package.json ./ -RUN yarn install +RUN yarn install --network-timeout 1000000 COPY front . -COPY --from=messages /usr/src/ts-proto-generated/protos src/Messages/ts-proto-generated +COPY --from=proto-builder /usr/src/ts-proto-generated/protos src/Messages/ts-proto-generated RUN sed -i 's/import { Observable } from "rxjs";/import type { Observable } from "rxjs";/g' src/Messages/ts-proto-generated/messages.ts -COPY --from=messages /usr/src/JsonMessages src/Messages/JsonMessages +COPY --from=proto-builder /usr/src/JsonMessages src/Messages/JsonMessages RUN yarn run typesafe-i18n && yarn run build-iframe-api && yarn build # final production image -FROM nginx:mainline-alpine +FROM nginx:1.21.6-alpine COPY front/nginx.conf /etc/nginx/conf.d/default.conf COPY front/templater.sh / + COPY --from=builder /usr/src/dist /usr/share/nginx/html -CMD ["/bin/sh", "-c", "/templater.sh && envsubst < /usr/share/nginx/html/env-config.template.js > /usr/share/nginx/html/env-config.js && exec nginx -g 'daemon off;'"] +EXPOSE 80 +CMD ["/bin/sh", "-c", "/templater.sh && envsubst < /usr/share/nginx/html/env-config.template.js > /usr/share/nginx/html/env-config.js && exec nginx -g 'daemon off;'"] \ No newline at end of file diff --git a/front/public/.htaccess b/front/public/.htaccess deleted file mode 100644 index 92ea1eec..00000000 --- a/front/public/.htaccess +++ /dev/null @@ -1,26 +0,0 @@ -DirectoryIndex index.html - -# By default, Apache does not evaluate symbolic links if you did not enable this -# feature in your server configuration. Uncomment the following line if you -# install assets as symlinks or if you experience problems related to symlinks -# when compiling LESS/Sass/CoffeScript assets. -# Options FollowSymlinks - -# Disabling MultiViews prevents unwanted negotiation, e.g. "/index" should not resolve -# to the front controller "/index.php" but be rewritten to "/index.php/index". - - Options -MultiViews - - -RewriteEngine On - -RewriteBase / - -# If the requested filename exists, simply serve it. -# We only want to let Apache serve files and not directories. -# Rewrite all other queries starting with _ to index.ts. -RewriteCond %{REQUEST_FILENAME} !-f -RewriteRule "^[_@*]/" "/index.html" [L] -RewriteRule "^register/" "/index.html" [L] -RewriteRule "^login" "/index.html" [L] -RewriteRule "^jwt" "/index.html" [L] diff --git a/front/src/Components/Menu/ProfileSubMenu.svelte b/front/src/Components/Menu/ProfileSubMenu.svelte index 71466f07..818cc25b 100644 --- a/front/src/Components/Menu/ProfileSubMenu.svelte +++ b/front/src/Components/Menu/ProfileSubMenu.svelte @@ -9,7 +9,6 @@ getProfileUrl, } from "../../Stores/MenuStore"; import { selectCompanionSceneVisibleStore } from "../../Stores/SelectCompanionStore"; - import { loginSceneVisibleStore } from "../../Stores/LoginSceneStore"; import { selectCharacterSceneVisibleStore } from "../../Stores/SelectCharacterStore"; import { SelectCharacterScene, SelectCharacterSceneName } from "../../Phaser/Login/SelectCharacterScene"; import { connectionManager } from "../../Connexion/ConnectionManager"; diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index 2bfda83c..2f8ca376 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -182,6 +182,7 @@ export class GameScene extends DirtyScene { private followUsersColorStoreUnsubscribe!: Unsubscriber; private userIsJitsiDominantSpeakerStoreUnsubscriber!: Unsubscriber; private jitsiParticipantsCountStoreUnsubscriber!: Unsubscriber; + private availabilityStatusStoreUnsubscriber!: Unsubscriber; private biggestAvailableAreaStoreUnsubscribe!: () => void; MapUrlFile: string; @@ -714,7 +715,7 @@ export class GameScene extends DirtyScene { this.tryChangeShowVoiceIndicatorState(this.jitsiDominantSpeaker && this.jitsiParticipantsCount > 1); }); - availabilityStatusStore.subscribe((status) => { + this.availabilityStatusStoreUnsubscriber = availabilityStatusStore.subscribe((status) => { this.connection?.emitPlayerStatusChange(status); this.CurrentPlayer.setStatus(status); }); @@ -1649,6 +1650,7 @@ export class GameScene extends DirtyScene { this.biggestAvailableAreaStoreUnsubscribe(); this.userIsJitsiDominantSpeakerStoreUnsubscriber(); this.jitsiParticipantsCountStoreUnsubscriber(); + this.availabilityStatusStoreUnsubscriber(); iframeListener.unregisterAnswerer("getState"); iframeListener.unregisterAnswerer("loadTileset"); iframeListener.unregisterAnswerer("getMapData"); diff --git a/front/src/Stores/MediaStore.ts b/front/src/Stores/MediaStore.ts index dc0680dc..ea7eefb8 100644 --- a/front/src/Stores/MediaStore.ts +++ b/front/src/Stores/MediaStore.ts @@ -414,6 +414,13 @@ async function toggleConstraints(track: MediaStreamTrack, constraints: MediaTrac } } +// This promise is important to queue the calls to "getUserMedia" +// Otherwise, this can happen: +// User requests a start then a stop of the camera quickly +// The promise to start the cam starts. Before the promise is fulfilled, the camera is stopped. +// Then, the MediaStream of the camera start resolves (resulting in the LED being turned on instead of off) +let currentGetUserMediaPromise: Promise = Promise.resolve(undefined); + /** * A store containing the MediaStream object (or null if nothing requested, or Error if an error occurred) */ @@ -422,50 +429,59 @@ export const localStreamStore = derived, LocalS ($mediaStreamConstraintsStore, set) => { const constraints = { ...$mediaStreamConstraintsStore }; - async function initStream(constraints: MediaStreamConstraints) { - try { - if (currentStream) { - //we need stop all tracks to make sure the old stream will be garbage collected - //currentStream.getTracks().forEach((t) => t.stop()); - } - currentStream = await navigator.mediaDevices.getUserMedia(constraints); - set({ - type: "success", - stream: currentStream, - }); - return; - } catch (e) { - if (constraints.video !== false || constraints.audio !== false) { - console.info( - "Error. Unable to get microphone and/or camera access. Trying audio only.", - constraints, - e - ); - // TODO: does it make sense to pop this error when retrying? - set({ - type: "error", - error: e instanceof Error ? e : new Error("An unknown error happened"), + function initStream(constraints: MediaStreamConstraints): Promise { + currentGetUserMediaPromise = currentGetUserMediaPromise.then(() => { + return navigator.mediaDevices + .getUserMedia(constraints) + .then((stream) => { + // Close old stream + if (currentStream) { + //we need stop all tracks to make sure the old stream will be garbage collected + currentStream.getTracks().forEach((t) => t.stop()); + } + + currentStream = stream; + set({ + type: "success", + stream: currentStream, + }); + return stream; + }) + .catch((e) => { + if (constraints.video !== false || constraints.audio !== false) { + console.info( + "Error. Unable to get microphone and/or camera access. Trying audio only.", + constraints, + e + ); + // TODO: does it make sense to pop this error when retrying? + set({ + type: "error", + error: e instanceof Error ? e : new Error("An unknown error happened"), + }); + // Let's try without video constraints + if (constraints.video !== false) { + requestedCameraState.disableWebcam(); + } + if (constraints.audio !== false) { + requestedMicrophoneState.disableMicrophone(); + } + } else if (!constraints.video && !constraints.audio) { + set({ + type: "error", + error: new MediaStreamConstraintsError(), + }); + } else { + console.info("Error. Unable to get microphone and/or camera access.", constraints, e); + set({ + type: "error", + error: e instanceof Error ? e : new Error("An unknown error happened"), + }); + } + return undefined; }); - // Let's try without video constraints - if (constraints.video !== false) { - requestedCameraState.disableWebcam(); - } - if (constraints.audio !== false) { - requestedMicrophoneState.disableMicrophone(); - } - } else if (!constraints.video && !constraints.audio) { - set({ - type: "error", - error: new MediaStreamConstraintsError(), - }); - } else { - console.info("Error. Unable to get microphone and/or camera access.", constraints, e); - set({ - type: "error", - error: e instanceof Error ? e : new Error("An unknown error happened"), - }); - } - } + }); + return currentGetUserMediaPromise; } if (navigator.mediaDevices === undefined) { @@ -491,46 +507,62 @@ export const localStreamStore = derived, LocalS } } - applyMicrophoneConstraints(currentStream, constraints.audio || false).catch((e) => console.error(e)); - applyCameraConstraints(currentStream, constraints.video || false).catch((e) => console.error(e)); - - if (implementCorrectTrackBehavior) { - //on good navigators like firefox, we can instantiate the stream once and simply disable or enable the tracks as needed - if (currentStream === null) { - // we need to assign a first value to the stream because getUserMedia is async - set({ - type: "success", - stream: null, - }); - initStream(constraints).catch((e) => { - set({ - type: "error", - error: e instanceof Error ? e : new Error("An unknown error happened"), - }); - }); - } - } else { - //on bad navigators like chrome, we have to stop the tracks when we mute and reinstantiate the stream when we need to unmute - if (constraints.audio === false && constraints.video === false) { - currentStream = null; - set({ - type: "success", - stream: null, - }); - } //we reemit the stream if it was muted just to be sure - else if (constraints.audio /* && !oldConstraints.audio*/ || (!oldConstraints.video && constraints.video)) { - initStream(constraints).catch((e) => { - set({ - type: "error", - error: e instanceof Error ? e : new Error("An unknown error happened"), - }); - }); - } - oldConstraints = { - video: !!constraints.video, - audio: !!constraints.audio, - }; + if (currentStream === null) { + // we need to assign a first value to the stream because getUserMedia is async + set({ + type: "success", + stream: null, + }); } + + (async () => { + await applyMicrophoneConstraints(currentStream, constraints.audio || false).catch((e) => console.error(e)); + await applyCameraConstraints(currentStream, constraints.video || false).catch((e) => console.error(e)); + + if (implementCorrectTrackBehavior) { + //on good navigators like firefox, we can instantiate the stream once and simply disable or enable the tracks as needed + if (currentStream === null) { + initStream(constraints).catch((e) => { + set({ + type: "error", + error: e instanceof Error ? e : new Error("An unknown error happened"), + }); + }); + } + } else { + //on bad navigators like chrome, we have to stop the tracks when we mute and reinstantiate the stream when we need to unmute + if (constraints.audio === false && constraints.video === false) { + currentGetUserMediaPromise = currentGetUserMediaPromise.then(() => { + if (currentStream) { + //we need stop all tracks to make sure the old stream will be garbage collected + currentStream.getTracks().forEach((t) => t.stop()); + } + + currentStream = null; + set({ + type: "success", + stream: null, + }); + return undefined; + }); + } //we reemit the stream if it was muted just to be sure + else if ( + constraints.audio /* && !oldConstraints.audio*/ || + (!oldConstraints.video && constraints.video) + ) { + initStream(constraints).catch((e) => { + set({ + type: "error", + error: e instanceof Error ? e : new Error("An unknown error happened"), + }); + }); + } + oldConstraints = { + video: !!constraints.video, + audio: !!constraints.audio, + }; + } + })().catch((e) => console.error(e)); } ); diff --git a/front/style/style.scss b/front/style/style.scss index b5217aca..f031fdc9 100644 --- a/front/style/style.scss +++ b/front/style/style.scss @@ -915,3 +915,8 @@ div.action.danger p.action-body{ .emoji-picker__emojis { font-family: 'Twemoji Mozilla' !important; } + +// TODO: remove once https://github.com/nostalgic-css/NES.css/pull/482 is released +.nes-container.is-rounded { + border-image-repeat: stretch; +} diff --git a/pusher/Dockerfile b/pusher/Dockerfile index 060c4dc2..99f4d33f 100644 --- a/pusher/Dockerfile +++ b/pusher/Dockerfile @@ -1,5 +1,9 @@ +# The building of ProtoBuf "messages" must be done out of Docker because grpc-node does not ship with ARM64 binaries. +# See: https://github.com/grpc/grpc-node/issues/1405 +# When the issue above is closed, we can move back messages building inside Dockerfile + # protobuf build -FROM node:14.18.2-buster-slim@sha256:20bedf0c09de887379e59a41c04284974f5fb529cf0e13aab613473ce298da3d as messages +FROM node:1.18.2-buster-slim@sha256:20bedf0c09de887379e59a41c04284974f5fb529cf0e13aab613473ce298da3d as proto-builder WORKDIR /usr/src COPY messages/yarn.lock messages/package.json ./ RUN yarn install @@ -7,18 +11,18 @@ COPY messages . RUN yarn proto # typescript build -FROM node:14.18.2-buster-slim@sha256:20bedf0c09de887379e59a41c04284974f5fb529cf0e13aab613473ce298da3d as builder +FROM node:16.15-buster-slim@sha256:9ad2f889d4a15ef94e40ac75e95c28daa34073dbc25d7b1e619caacc6b83623c as builder WORKDIR /usr/src COPY pusher/yarn.lock pusher/package.json ./ RUN yarn install COPY pusher . -COPY --from=messages /usr/src/generated src/Messages/generated -COPY --from=messages /usr/src/JsonMessages src/Messages/JsonMessages +COPY --from=proto-builder /usr/src/generated src/Messages/generated +COPY --from=proto-builder /usr/src/JsonMessages src/Messages/JsonMessages ENV NODE_ENV=production RUN yarn run tsc # final production image -FROM node:14.18.2-buster-slim@sha256:20bedf0c09de887379e59a41c04284974f5fb529cf0e13aab613473ce298da3d +FROM node:16.15-buster-slim@sha256:9ad2f889d4a15ef94e40ac75e95c28daa34073dbc25d7b1e619caacc6b83623c WORKDIR /usr/src COPY pusher/yarn.lock pusher/package.json ./ ENV NODE_ENV=production diff --git a/pusher/Dockerfile.prod b/pusher/Dockerfile.prod index 772532f0..a617ed84 100644 --- a/pusher/Dockerfile.prod +++ b/pusher/Dockerfile.prod @@ -1,4 +1,4 @@ -FROM node:12.19.0-slim +FROM node:16.15-buster-slim@sha256:9ad2f889d4a15ef94e40ac75e95c28daa34073dbc25d7b1e619caacc6b83623c RUN mkdir -p /home/node/app && chown -R node:node /home/node/app WORKDIR /home/node/app diff --git a/uploader/Dockerfile b/uploader/Dockerfile index 321ef853..e01a6400 100644 --- a/uploader/Dockerfile +++ b/uploader/Dockerfile @@ -1,5 +1,5 @@ # typescript build -FROM node:14.15.4-buster-slim@sha256:cbae886186467bbfd274b82a234a1cdfbbd31201c2a6ee63a6893eefcf3c6e76 as builder +FROM node:16.15-buster-slim@sha256:9ad2f889d4a15ef94e40ac75e95c28daa34073dbc25d7b1e619caacc6b83623c as builder2 WORKDIR /usr/src COPY uploader/yarn.lock uploader/package.json ./ RUN yarn install @@ -8,12 +8,12 @@ ENV NODE_ENV=production RUN yarn run tsc # final production image -FROM node:14.15.4-buster-slim@sha256:cbae886186467bbfd274b82a234a1cdfbbd31201c2a6ee63a6893eefcf3c6e76 +FROM node:16.15-buster-slim@sha256:9ad2f889d4a15ef94e40ac75e95c28daa34073dbc25d7b1e619caacc6b83623c WORKDIR /usr/src COPY uploader/yarn.lock uploader/package.json ./ ENV NODE_ENV=production RUN yarn install --production -COPY --from=builder /usr/src/dist /usr/src/dist +COPY --from=builder2 /usr/src/dist /usr/src/dist USER node -CMD ["yarn", "run", "runprod"] +CMD ["yarn", "run", "runprod"] \ No newline at end of file diff --git a/uploader/package.json b/uploader/package.json index 62b55c07..3abd5388 100644 --- a/uploader/package.json +++ b/uploader/package.json @@ -43,7 +43,7 @@ "mkdirp": "^1.0.4", "prom-client": "^12.0.0", "query-string": "^6.13.3", - "uWebSockets.js": "uNetworking/uWebSockets.js#v18.5.0", + "uWebSockets.js": "uNetworking/uWebSockets.js#v20.10.0", "uuidv4": "^6.0.7" }, "devDependencies": { @@ -51,14 +51,14 @@ "@types/circular-json": "^0.4.0", "@types/debug": "^4.1.5", "@types/http-status-codes": "^1.2.0", - "@types/jasmine": "^3.5.10", + "@types/jasmine": "^4.0.3", "@types/jsonwebtoken": "^8.3.8", "@typescript-eslint/eslint-plugin": "^2.26.0", "@typescript-eslint/parser": "^2.26.0", "@types/mkdirp": "^1.0.1", "@types/uuidv4": "^5.0.0", "eslint": "^6.8.0", - "jasmine": "^3.5.0", + "jasmine": "^4.0.3", "ts-node-dev": "^1.0.0-pre.44", "typescript": "^3.8.3" } diff --git a/uploader/yarn.lock b/uploader/yarn.lock index 26868e3f..50646717 100644 --- a/uploader/yarn.lock +++ b/uploader/yarn.lock @@ -52,10 +52,10 @@ dependencies: http-status-codes "*" -"@types/jasmine@^3.5.10": - version "3.6.2" - resolved "https://registry.yarnpkg.com/@types/jasmine/-/jasmine-3.6.2.tgz#02f64450016f7de70f145d698be311136d7c6374" - integrity sha512-AzfesNFLvOs6Q1mHzIsVJXSeUnqVh4ZHG8ngygKJfbkcSLwzrBVm/LKa+mR8KrOfnWtUL47112gde1MC0IXqpQ== +"@types/jasmine@^4.0.3": + version "4.0.3" + resolved "https://registry.yarnpkg.com/@types/jasmine/-/jasmine-4.0.3.tgz#097ce710d70eb7f3662e96c1f75824dd22c27d5c" + integrity sha512-Opp1LvvEuZdk8fSSvchK2mZwhVrsNT0JgJE9Di6MjnaIpmEXM8TLCPPrVtNTYh8+5MPdY8j9bAHMu2SSfwpZJg== "@types/json-schema@^7.0.3": version "7.0.6" @@ -866,18 +866,18 @@ isexe@^2.0.0: resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= -jasmine-core@~3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/jasmine-core/-/jasmine-core-3.6.0.tgz#491f3bb23941799c353ceb7a45b38a950ebc5a20" - integrity sha512-8uQYa7zJN8hq9z+g8z1bqCfdC8eoDAeVnM5sfqs7KHv9/ifoJ500m018fpFc7RDaO6SWCLCXwo/wPSNcdYTgcw== +jasmine-core@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/jasmine-core/-/jasmine-core-4.1.0.tgz#2377349b0e8bfd3fbdb36c9e4f09e3b1a17cf5c2" + integrity sha512-8E8BiffCL8sBwK1zU9cbavLe8xpJAgOduSJ6N8PJVv8VosQ/nxVTuXj2kUeHxTlZBVvh24G19ga7xdiaxlceKg== -jasmine@^3.5.0: - version "3.6.3" - resolved "https://registry.yarnpkg.com/jasmine/-/jasmine-3.6.3.tgz#520cd71f76bd8251e9f566b622e13602e9ddcf26" - integrity sha512-Th91zHsbsALWjDUIiU5d/W5zaYQsZFMPTdeNmi8GivZPmAaUAK8MblSG3yQI4VMGC/abF2us7ex60NH1AAIMTA== +jasmine@^4.0.3: + version "4.1.0" + resolved "https://registry.yarnpkg.com/jasmine/-/jasmine-4.1.0.tgz#0de347ca8bb6cc764b0ed186ae4cfc45bd64bdc4" + integrity sha512-4VhjbUgwfNS9CBnUMoSWr9tdNgOoOhNIjAD8YRxTn+PmOf4qTSC0Uqhk66dWGnz2vJxtNIU0uBjiwnsp4Ud9VA== dependencies: glob "^7.1.6" - jasmine-core "~3.6.0" + jasmine-core "^4.1.0" js-tokens@^4.0.0: version "4.0.0" @@ -1645,9 +1645,9 @@ typescript@^3.8.3: resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.7.tgz#98d600a5ebdc38f40cb277522f12dc800e9e25fa" integrity sha512-BLbiRkiBzAwsjut4x/dsibSTB6yWpwT5qWmC2OfuCg3GgVQCSgMs4vEctYPhsaGtd0AeuuHMkjZ2h2WG8MSzRw== -uWebSockets.js@uNetworking/uWebSockets.js#v18.5.0: - version "18.5.0" - resolved "https://codeload.github.com/uNetworking/uWebSockets.js/tar.gz/9b1605d2db82981cafe69dbe356e10ce412f5805" +uWebSockets.js@uNetworking/uWebSockets.js#v20.10.0: + version "20.10.0" + resolved "https://codeload.github.com/uNetworking/uWebSockets.js/tar.gz/806df48c9da86af7b3341f3e443388c7cd15c3de" uri-js@^4.2.2: version "4.4.0"