Skip to content

Commit

Permalink
feat: Add ability to create guest links with password (SQSERVICES-197…
Browse files Browse the repository at this point in the history
…5) (#15014)

* feat: Add ability to create guest links with password (SQSERVICES-1975)

* feat: Add GuestLinkPasswordModal

* join with login

* sso password

* joing with deeplink

* clean up copies

* fix error

* Update src/script/auth/component/GuestLinkPasswordModal.tsx

Co-authored-by: Virgile <[email protected]>

* backward compatibility

* Update src/script/auth/component/GuestLinkPasswordModal.tsx

Co-authored-by: Przemysław Jóźwik <[email protected]>

* use on if

* fix backenderror

* fix type error

* BackendErrorlabel

* fix type error

* fix state bug

* add loading state

* bump core

* use api-client supportsGuestLinksWithPassword

* feat: conversation name

* add URL_LEARN_MORE_ABOUT_GUEST_LINKS

* throw error

* runfix: password not secure option

* copy your password reminder message

* The text inputs wrong labels

* disabled state

* design review for joining on desktop

* remove log

* disabled copy to clipboard

* border color on focus

* rename

* fix redirect bug

* invalid password error handling

* login and single sign on password error handling

* fix broken tests

* fix ts error

* add password conditions check

* add modal close button

* add close button to login

* close modal on sso with link pass

* fix primary button disabled

* password copy

* feat: update guest link passwords for new convo join page

* fix: issue with some edge cases not working

* chore: remove error throw

* fix: remove form param submission bug

* chore: remove password from error on L132

* chore: missing error catch

* feat: possible fix for open issues

* fix: password verification

* chore: condense password regex

* feat: update primary modal

* chore: disable guest link passwords feature

* chore: merge dev

---------

Co-authored-by: Virgile <[email protected]>
Co-authored-by: Przemysław Jóźwik <[email protected]>
Co-authored-by: Timothy Le Bon <[email protected]>
  • Loading branch information
4 people authored Dec 20, 2023
1 parent 75f012d commit e820de8
Show file tree
Hide file tree
Showing 41 changed files with 1,698 additions and 240 deletions.
11 changes: 0 additions & 11 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ jobs:
build:
name: Build Docker image and Helm Chart
runs-on: buildjet-8vcpu-ubuntu-2204

outputs:
wire_builds_target_branches: ${{ steps.output_target_branches.outputs.wire_builds_target_branches }}
image_tag: ${{ steps.push_docker_image.outputs.image_tag }}
Expand All @@ -38,18 +37,15 @@ jobs:
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 16.x
cache: 'yarn'

- name: Set environment variables
run: |
echo "BRANCH_NAME=$(git branch --show-current)" >> $GITHUB_ENV
echo "TAG=$(git tag --points-at ${{github.sha}})" >> $GITHUB_ENV
- name: Print environment variables
run: |
echo -e "BRANCH_NAME = ${BRANCH_NAME}"
Expand Down Expand Up @@ -179,15 +175,13 @@ jobs:
helm package ./charts/webapp
helm s3 push webapp-*.tgz charts-webapp
publish_wire_builds:
name: Bump webapp chart in wire-builds
runs-on: ubuntu-latest
needs: build
strategy:
matrix:
target_branch: ${{fromJSON(needs.build.outputs.wire_builds_target_branches)}}

steps:
- name: Check out wire-builds
uses: actions/checkout@v4
Expand All @@ -196,7 +190,6 @@ jobs:
token: ${{secrets.WIRE_BUILDS_WRITE_ACCESS_GH_TOKEN}}
ref: ${{matrix.target_branch}}
fetch-depth: 1

- name: Create new build in wire-build
shell: bash
run: |
Expand Down Expand Up @@ -231,14 +224,12 @@ jobs:
echo '::set-output name=exists::true'
echo "::set-output name=releaseInfo::$(cat ${ARTIFACT_LOCAL_PATH})"
fi
- name: Checking out 'wire-server'
uses: actions/checkout@v4
if: ${{ steps.release-info-file.outputs.exists == 'true' }}
with:
repository: 'wireapp/wire-server'
fetch-depth: 1

- name: Changing Helm value of the webapp chart
id: change-helm-value
if: ${{ steps.release-info-file.outputs.exists == 'true' }}
Expand All @@ -249,7 +240,6 @@ jobs:
echo "Upgrade webapp version to ${{needs.build.outputs.image_tag}}" > ./changelog.d/0-release-notes/webapp-upgrade
git add ./changelog.d/0-release-notes/webapp-upgrade
echo "::set-output name=releaseUrl::${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/releases/tag/${{needs.build.outputs.release_name}}"
- name: Creating Pull Request
id: create-pr
if: ${{ steps.release-info-file.outputs.exists == 'true' }}
Expand All @@ -264,7 +254,6 @@ jobs:
body: |
Image tag: `${{needs.build.outputs.image_tag}}`
Release: [`${{needs.build.outputs.release_name}}`](${{ steps.change-helm-value.outputs.releaseUrl }})
- name: Printing Pull Request URL
if: ${{ steps.release-info-file.outputs.exists == 'true' }}
shell: bash
Expand Down
228 changes: 228 additions & 0 deletions .github/workflows/test_build_deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,228 @@
name: CI

on:
push:
branches: [master, dev, edge, avs, mobile, acc]
tags:
- '*staging*'
- '*production*'
pull_request:
branches: [master, dev, edge, avs, mobile, acc]

concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true

jobs:
test_build_deploy:
runs-on: buildjet-8vcpu-ubuntu-2204

env:
TEST_COVERAGE_FAIL_THRESHOLD: 45
TEST_COVERAGE_WARNING_THRESHOLD: 60
DEPLOYMENT_RECOVERY_TIMEOUT_SECONDS: 150
AWS_APPLICATION_NAME: Webapp
AWS_BUILD_ZIP_PATH: server/dist/s3/ebs.zip
COMMIT_URL: ${{github.event.head_commit.url}}
COMMITTER: ${{github.event.head_commit.committer.name}}

steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 16.x
cache: 'yarn'

- name: Set environment variables
run: |
echo "BRANCH_NAME=$(git branch --show-current)" >> $GITHUB_ENV
echo "TAG=$(git tag --points-at ${{github.sha}})" >> $GITHUB_ENV
echo "PR_LAST_COMMIT_MESSAGE=$(git log --format=%B -n 1 ${{github.event.after}} | head -n 1)" >> $GITHUB_ENV
- name: Set TITLE and BUILD_DESKTOP
env:
PR_TITLE: ${{github.event.pull_request.title || env.PR_LAST_COMMIT_MESSAGE}}
run: |
echo "TITLE=${PR_TITLE}" >> $GITHUB_ENV
echo "BUILD_DESKTOP=${{contains(env.TAG, 'staging') || contains(env.TAG, 'production') || contains(env.PR_LAST_COMMIT_MESSAGE, '+Desktop')}}" >> $GITHUB_ENV
- name: Print environment variables
run: |
echo -e "BRANCH_NAME = ${BRANCH_NAME}"
echo -e "TAG = ${TAG}"
echo -e "TITLE = ${TITLE}"
echo -e "PR_LAST_COMMIT_MESSAGE = ${PR_LAST_COMMIT_MESSAGE}"
echo -e "COMMIT_URL = ${COMMIT_URL}"
echo -e "COMMITTER = ${COMMITTER}"
echo -e "BUILD_DESKTOP = ${BUILD_DESKTOP}"
- name: Skip CI
if: |
contains(env.TITLE || env.PR_LAST_COMMIT_MESSAGE, '[skip ci]') ||
contains(env.TITLE || env.PR_LAST_COMMIT_MESSAGE, '[ci skip]')
uses: andymckay/[email protected]

- name: Install JS dependencies
run: yarn --immutable

- name: Test
run: |
set -o pipefail
yarn test --coverage --coverage-reporters=lcov --detectOpenHandles=false 2>&1 | tee ./unit-tests.log
- name: Monitor coverage
uses: codecov/[email protected]
with:
fail_ci_if_error: false
files: ./coverage/lcov.info
flags: unittests

- uses: kanga333/variable-mapper@master
with:
# We try to map a branch to a dev environment
key: '${{github.ref}}'
map: |
{
"dev": { "dev_env": "wire-webapp-dev-al2" },
"master": { "dev_env": "wire-webapp-master-al2" }
}
- uses: kanga333/variable-mapper@master
with:
# We try to map a branch to a dev environment
key: '${{github.ref}}'
map: |
{
"dev": { "preprod_env": "wire-webapp-edge-al2" }
}
- uses: kanga333/variable-mapper@master
with:
# We try to map a tag to a dev environment
key: '${{env.TAG}}'
map: |
{
"production": { "prod_env": "wire-webapp-prod-al2" },
"staging": { "prod_env": "wire-webapp-staging-al2" }
}
- name: Build
if: env.prod_env || env.dev_env
run: yarn build:prod

# Stage 1: https://wire-webapp-edge.zinfra.io/
- name: Deploy to dev env
if: env.dev_env
uses: einaregilsson/beanstalk-deploy@v21
with:
application_name: ${{env.AWS_APPLICATION_NAME}}
aws_access_key: ${{secrets.WEBTEAM_AWS_ACCESS_KEY_ID}}
aws_secret_key: ${{secrets.WEBTEAM_AWS_SECRET_ACCESS_KEY}}
deployment_package: ${{env.AWS_BUILD_ZIP_PATH}}
environment_name: ${{env.dev_env}}
region: eu-central-1
use_existing_version_if_available: true
version_description: ${{github.sha}}
version_label: ${{github.run_id}}
wait_for_deployment: false
wait_for_environment_recovery: ${{env.DEPLOYMENT_RECOVERY_TIMEOUT_SECONDS}}

- name: Deploy to pre-prod env
if: env.preprod_env
uses: einaregilsson/beanstalk-deploy@v21
with:
application_name: ${{env.AWS_APPLICATION_NAME}}
aws_access_key: ${{secrets.WEBTEAM_AWS_ACCESS_KEY_ID}}
aws_secret_key: ${{secrets.WEBTEAM_AWS_SECRET_ACCESS_KEY}}
deployment_package: ${{env.AWS_BUILD_ZIP_PATH}}
environment_name: ${{env.preprod_env}}
region: eu-central-1
use_existing_version_if_available: true
version_description: ${{github.sha}}
version_label: ${{github.run_id}}
wait_for_deployment: false
wait_for_environment_recovery: ${{env.DEPLOYMENT_RECOVERY_TIMEOUT_SECONDS}}

- name: Deploy to prod env
if: env.prod_env
uses: einaregilsson/beanstalk-deploy@v21
with:
application_name: ${{env.AWS_APPLICATION_NAME}}
aws_access_key: ${{secrets.WEBTEAM_AWS_ACCESS_KEY_ID}}
aws_secret_key: ${{secrets.WEBTEAM_AWS_SECRET_ACCESS_KEY}}
deployment_package: ${{env.AWS_BUILD_ZIP_PATH}}
environment_name: ${{env.prod_env}}
region: eu-central-1
use_existing_version_if_available: true
version_description: ${{github.sha}}
version_label: ${{env.TAG}}-${{github.run_id}}
wait_for_deployment: false
wait_for_environment_recovery: ${{env.DEPLOYMENT_RECOVERY_TIMEOUT_SECONDS}}

- name: Generate changelog for production release
if: contains(env.TAG, 'production')
run: yarn changelog:production

- name: Create GitHub production release
id: create_release_production
if: contains(env.TAG, 'production')
uses: softprops/action-gh-release@v1
env:
GITHUB_TOKEN: ${{github.token}}
with:
tag_name: ${{env.TAG}}
name: ${{env.TAG}}
body_path: ./CHANGELOG.md
files: ./unit-tests.log
draft: false
prerelease: false

- name: Announce production release
if: contains(env.TAG, 'production')
uses: wireapp/[email protected]
with:
email: ${{secrets.WIRE_BOT_EMAIL}}
password: ${{secrets.WIRE_BOT_PASSWORD}}
conversation: 1784ed44-7c32-4984-b5e2-0b4d55b034ed
send_text: 'The web team just rolled out a new version of [Wire for Web](https://app.wire.com/). You can find what has changed in our [GitHub release notes](https://github.com/wireapp/wire-webapp/releases/latest).\n\nPlease note that the rollout can take up to 30 minutes to be fully deployed on all nodes. You can check here if you get already served our latest version from today: https://app.wire.com/version'

- name: Generate changelog for staging release
if: contains(env.TAG, 'staging')
run: yarn changelog:staging

- name: Create GitHub staging release
id: create_release_staging
if: contains(env.TAG, 'staging')
uses: softprops/action-gh-release@v1
env:
GITHUB_TOKEN: ${{github.token}}
with:
tag_name: ${{env.TAG}}
name: ${{env.TAG}}
body_path: ./CHANGELOG.md
files: ./unit-tests.log
draft: false
prerelease: true

- name: Announce staging release
if: contains(env.TAG, 'staging')
uses: wireapp/[email protected]
with:
email: ${{secrets.WIRE_BOT_EMAIL}}
password: ${{secrets.WIRE_BOT_PASSWORD}}
conversation: '697c93e8-0b13-4204-a35e-59270462366a'
send_text: 'Staging bump for commit **${{github.sha}}** ("${{env.TITLE}}") done! 🏁'

- name: Notify CI error
if: failure() && github.event_name != 'pull_request'
uses: wireapp/[email protected]
with:
email: ${{secrets.WIRE_BOT_EMAIL}}
password: ${{secrets.WIRE_BOT_PASSWORD}}
conversation: 'b2cc7120-4154-4be4-b0c0-45a8c361c4d1'
send_text: '${{env.COMMITTER}} broke the "${{env.BRANCH_NAME}}" branch on "${{github.repository}}" with [${{env.TITLE}}](${{env.COMMIT_URL}}) 🌵'
1 change: 1 addition & 0 deletions server/config/client.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ export function generateConfig(params: ConfigGeneratorParams, env: Env) {
MLS_LEARN_MORE: env.URL_SUPPORT_MLS_LEARN_MORE,
PRIVACY_VERIFY_FINGERPRINT: env.URL_SUPPORT_PRIVACY_VERIFY_FINGERPRINT,
SCREEN_ACCESS_DENIED: env.URL_SUPPORT_SCREEN_ACCESS_DENIED,
LEARN_MORE_ABOUT_GUEST_LINKS: env.URL_LEARN_MORE_ABOUT_GUEST_LINKS,
NON_FEDERATING_INFO: env.URL_SUPPORT_NON_FEDERATING_INFO,
OAUTH_LEARN_MORE: env.URL_SUPPORT_OAUTH_LEARN_MORE,
OFFLINE_BACKEND: env.URL_SUPPORT_OFFLINE_BACKEND,
Expand Down
2 changes: 2 additions & 0 deletions server/config/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,8 @@ export type Env = {

URL_SUPPORT_SCREEN_ACCESS_DENIED: string;

URL_LEARN_MORE_ABOUT_GUEST_LINKS: string;

URL_SUPPORT_NON_FEDERATING_INFO: string;

URL_SUPPORT_OAUTH_LEARN_MORE: string;
Expand Down
32 changes: 32 additions & 0 deletions src/i18n/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"BackendError.LABEL.CONVERSATION_CODE_NOT_FOUND": "This link is no longer valid. Ask the person who invited you how to join.",
"BackendError.LABEL.CONVERSATION_NOT_FOUND": "CONVERSATION_NOT_FOUND",
"BackendError.LABEL.CONVERSATION_TOO_MANY_MEMBERS": "This conversation has reached the limit of participants",
"BackendErrorLabel.INVALID_CONVERSATION_PASSWORD": "The password is incorrect, please try again.",
"BackendError.LABEL.EMAIL_EXISTS": "This email address is already in use. {supportEmailExistsLink}",
"BackendError.LABEL.EMAIL_REQUIRED": "You can’t use your username as two-factor authentication is activated. Please log in with your email instead.",
"BackendError.LABEL.HANDLE_EXISTS": "This username is already taken",
Expand Down Expand Up @@ -685,8 +686,25 @@
"guestOptionsCreateLink": "Create link",
"guestOptionsInfoHeader": "Invite others with a link",
"guestOptionsInfoText": "Invite others with a link to this conversation. Anyone with the link can join the conversation, even if they don’t have {{brandName}}.",
"guestOptionsInfoPasswordSecured": "Link is password secured",
"guestOptionsInfoTextWithPassword": "Users are asked to enter the password before they can join the conversation with a guest link.",
"guestOptionsInfoTextForgetPassword": "Forgot password? Revoke the link and create a new one.",
"guestOptionsInfoModalTitle": "Create password secured link",
"guestOptionsInfoModalTitleSubTitle": "People who want to join the conversation via the guest link need to enter this password first.",
"guestOptionsInfoModalCancel": "Cancel",
"guestOptionsInfoModalFormLabel": "Guest link password",
"guestOptionsInfoModalAction": "Create Link",
"guestOptionsInfoModalTitleBoldSubTitle": "You can't change the password later. Make sure to copy and store it.",
"guestOptionsInfoTextSecureWithPassword": "You can also secure the link with a password.",
"guestOptionsPasswordRadioLabel": "Guest link password",
"guestOptionsPasswordRadioOptionSecured": "Password secured",
"guestOptionsPasswordRadioOptionNotSecured": "Not password secured",
"guestOptionsPasswordCopyToClipboard": "Copy Password",
"guestOptionsPasswordCopyToClipboardSuccess": "Password Copied!",
"guestOptionsPasswordForceToCopy": "You need to copy the password so that you can store and share it with people you want to invite.",
"guestOptionsRevokeLink": "Revoke link",
"guestOptionsTitle": "Guests",
"generatePassword": "Generate password",
"guestRoomConversationBadge": "[bold]Guests[/bold] are present",
"guestRoomConversationBadgeExternal": "[bold]Externals[/bold] are present",
"guestRoomConversationBadgeExternalAndGuest": "[bold]Externals[/bold] and [bold]guests[/bold] are present",
Expand All @@ -709,6 +727,15 @@
"guestRoomToggleInfoDisabled": "You can't disable the guest option in this conversation, as it has been created by someone from another team.",
"guestRoomToggleInfoExtended": "Open this conversation to people outside your team. You can always change it later.",
"guestRoomToggleInfoHead": "Guest Links",
"guestLinkPasswordModal.headline": "{conversationName} \n Enter password",
"guestLinkPasswordModal.headlineDefault": "Group Conversation \n Enter password",
"guestLinkPasswordModal.description": "Please enter the password you have received with the access link for this conversation.",
"guestLinkPasswordModal.conversationPasswordProtected": "This conversation is password protected.",
"guestLinkPasswordModal.passwordInputLabel": "Conversation password",
"guestLinkPasswordModal.passwordInputPlaceholder": "Enter Conversation password",
"guestLinkPasswordModal.learnMoreLink": "Learn more about guest links",
"guestLinkPasswordModal.joinConversation": "Join Conversation",
"guestLinkPasswordModal.passwordIncorrect": "Password is incorrect, please try again.",
"guestRoomToggleName": "Allow Guests",
"historyInfo.learnMore": "Learn more",
"historyInfo.noHistoryHeadline": "It’s the first time you’re using {brandName} on this device.",
Expand Down Expand Up @@ -929,6 +956,11 @@
"modalConversationGuestOptionsGetCodeMessage": "Could not get access link.",
"modalConversationGuestOptionsRequestCodeMessage": "Could not request access link. Please try again.",
"modalConversationGuestOptionsRevokeCodeMessage": "Could not revoke access link. Please try again.",
"modalGuestLinkJoinPlaceholder": "Enter password",
"modalGuestLinkJoinConfirmPlaceholder": "Confirm your password",
"modalGuestLinkJoinLabel": "Set password",
"modalGuestLinkJoinConfirmLabel": "Confirm password",
"modalGuestLinkJoinHelperText": "Use at least {{minPasswordLength}} characters, with one lowercase letter, one capital letter, a number, and a special character.",
"modalConversationJoinConfirm": "Join",
"modalConversationJoinFullHeadline": "You could not join the conversation",
"modalConversationJoinFullMessage": "The conversation is full.",
Expand Down
Loading

0 comments on commit e820de8

Please sign in to comment.