Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
cd1701a
feat: basic UI structure
tlebon Feb 22, 2023
da4d9c7
chore: add some validation for the params
tlebon Feb 22, 2023
7b3e1c2
chore: remove errors
tlebon Feb 22, 2023
6c667af
chore: more structure added
tlebon Feb 23, 2023
02e54a2
chore: update redux to add getTeam action
tlebon Feb 27, 2023
419021c
fix: get redux working correctly with auth
tlebon Feb 27, 2023
6baeb80
feat: improve routing
tlebon Feb 28, 2023
d4a84ac
feat: display team image, improved styling
tlebon Mar 1, 2023
eed53b8
chore: get application name from BE
tlebon Mar 7, 2023
a492a6f
chore: add oauth calls
tlebon Mar 7, 2023
f9579ae
chore: merge dev
tlebon Mar 14, 2023
728ed3e
chore: update api client
tlebon Mar 15, 2023
5176729
chore: add redirect for 2manyClients case
tlebon Mar 15, 2023
b245105
chore: update copy for 2manyclients case
tlebon Mar 16, 2023
0276e94
chore: add back initial redirect
tlebon Mar 20, 2023
08c7899
feat: pass redirect url
tlebon Mar 20, 2023
0f4fc94
chore: fix scope parsing
tlebon Mar 21, 2023
de0172c
chore: update for loading icon
tlebon Mar 22, 2023
67cf9f1
chore: remove client device name
tlebon Mar 22, 2023
e4067de
runfix: issue with missing team icon
tlebon Mar 22, 2023
3f0bd47
runfix: issue with client page
tlebon Mar 22, 2023
b9de86c
feat: improve styling
tlebon Mar 23, 2023
fe862aa
chore: styling
tlebon Mar 23, 2023
7773e81
chore: merge dev
tlebon Mar 23, 2023
9cbcf6d
chore: add translations
tlebon Mar 23, 2023
5291e2a
chore: update core
tlebon Mar 27, 2023
cd585b0
chore: resolve comments
tlebon Mar 27, 2023
cdabad4
chore: merge dev
tlebon Mar 27, 2023
a8b48c4
fix: other instances of formatted message cleanup
tlebon Mar 27, 2023
b8a7c5b
chore: move styles to individual file
tlebon Mar 28, 2023
dee8034
styles: fixing styling issues
tlebon Mar 29, 2023
550279e
chore: merge dev
tlebon Mar 29, 2023
20c19a8
chore: switch to URLSearchParams
tlebon Mar 29, 2023
0b1d886
chore: handle logout for error cases
tlebon Mar 30, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion src/i18n/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,7 @@
"clientManager.headline": "Remove a device",
"clientManager.logout": "Cancel process",
"clientManager.subhead": "Remove one of your other devices to start using {brandName} on this one.",
"clientManager.oauth": "You are adding a new device. Only 7 devices can be active. Remove one of your devices to start using Wire on this one ({device}).",
"collectionSectionAudio": "Audio",
"collectionSectionFiles": "Files",
"collectionSectionImages": "Images",
Expand Down Expand Up @@ -956,6 +957,18 @@
"notificationTitleGroup": "{{user}} in {{conversation}}",
"notificationVoiceChannelActivate": "Calling",
"notificationVoiceChannelDeactivate": "Called",
"oauth.headline": "Permissions",
"oauth.logout": "Switch account",
"oauth.cancel": "Don't Allow",
"oauth.allow": "Allow",
"oauth.subhead": "{app} requires your permission to:",
"oauth.learnMore": "<learnMore>Learn more</learnMore> about these permissions in the settings.",
"oauth.details": "If you allow the permissions listed, Wire™ will be able to connect to your calendar. It won’t see the content of your calendar, just the ones happening with Wire. If you don’t grant the permissions, you can’t use this add-in.",
"oauth.privacypolicy": "Wire's <privacypolicy>Privacy Policy</privacypolicy>",
"oauth.scope.write_conversations": "Create conversations",
"oauth.scope.write_conversations_code": "Create conversation guest links",
"oauth.scope.read_self": "Access user information",
"oauth.scope.read_feature_configs": "Access team feature configurations",
"ongoingAudioCall": "Ongoing audio call with {{conversationName}}.",
"ongoingGroupAudioCall": "Ongoing conference call with {{conversationName}}.",
"ongoingGroupVideoCall": "Ongoing video conference call with {{conversationName}}, your camera is {{cameraStatus}}.",
Expand Down Expand Up @@ -1309,4 +1322,4 @@
"wireMacos": "{{brandName}} for macOS",
"wireWindows": "{{brandName}} for Windows",
"wire_for_web": "{{brandName}} for Web"
}
}
3 changes: 1 addition & 2 deletions src/script/auth/component/AcceptNewsModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,7 @@ const AcceptNewsModal = ({onConfirm, onDecline}: Props) => {
<FormattedMessage
{...acceptNewsModalStrings.privacyDescription}
values={{
// eslint-disable-next-line react/display-name
strong: ((...chunks: any[]) => <strong>{chunks}</strong>) as any,
strong: (...chunks: any[]) => <strong>{chunks}</strong>,
}}
/>
</Text>
Expand Down
15 changes: 6 additions & 9 deletions src/script/auth/component/AccountForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -264,8 +264,7 @@ const AccountFormComponent = ({account, ...props}: Props & ConnectedProps & Disp
<FormattedMessage
{...accountFormStrings.termsAndPrivacyPolicy}
values={{
// eslint-disable-next-line react/display-name
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what was this one for 🤔 ?
Good that we could get rid of it 👍

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no clue, i guess our linter changed a while ago. maybe we turned off this rule where components need to be named?

privacypolicy: ((...chunks: string[] | React.ReactNode[]) => (
privacypolicy: (...chunks: string[] | React.ReactNode[]) => (
<a
target="_blank"
rel="noopener noreferrer"
Expand All @@ -274,9 +273,8 @@ const AccountFormComponent = ({account, ...props}: Props & ConnectedProps & Disp
>
{chunks}
</a>
)) as any,
// eslint-disable-next-line react/display-name
terms: ((...chunks: string[] | React.ReactNode[]) => (
),
terms: (...chunks: string[] | React.ReactNode[]) => (
<a
target="_blank"
rel="noopener noreferrer"
Expand All @@ -289,15 +287,14 @@ const AccountFormComponent = ({account, ...props}: Props & ConnectedProps & Disp
>
{chunks}
</a>
)) as any,
),
}}
/>
) : (
<FormattedMessage
{...accountFormStrings.terms}
values={{
// eslint-disable-next-line react/display-name
terms: ((...chunks: string[] | React.ReactNode[]) => (
terms: (...chunks: string[] | React.ReactNode[]) => (
<a
target="_blank"
rel="noopener noreferrer"
Expand All @@ -310,7 +307,7 @@ const AccountFormComponent = ({account, ...props}: Props & ConnectedProps & Disp
>
{chunks}
</a>
)) as any,
),
}}
/>
)}
Expand Down
7 changes: 7 additions & 0 deletions src/script/auth/component/ClientList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {connect} from 'react-redux';
import {useNavigate} from 'react-router-dom';
import {AnyAction, Dispatch} from 'redux';

import {UrlUtil} from '@wireapp/commons';
import {ContainerXS, Loading} from '@wireapp/react-ui-kit';

import {getLogger} from 'Util/Logger';
Expand Down Expand Up @@ -56,6 +57,7 @@ const ClientListComponent = ({
}: Props & ConnectedProps & DispatchProps) => {
const navigate = useNavigate();
const [showLoading, setShowLoading] = React.useState(false);
const isOauth = UrlUtil.hasURLParameter(QUERY_KEY.SCOPE);
const [currentlySelectedClient, setCurrentlySelectedClient] = React.useState<string | null>(null);

const setSelectedClient = (clientId: string) => {
Expand All @@ -76,6 +78,11 @@ const ClientListComponent = ({
await doInitializeClient(persist ? ClientType.PERMANENT : ClientType.TEMPORARY, password, SFAcode, entropy);
removeLocalStorage(QUERY_KEY.CONVERSATION_CODE);
removeLocalStorage(QUERY_KEY.JOIN_EXPIRES);

if (isOauth) {
return navigate(ROUTE.AUTHORIZE);
}

return navigate(ROUTE.HISTORY_INFO);
} catch (error) {
logger.error(error);
Expand Down
1 change: 0 additions & 1 deletion src/script/auth/component/UnsupportedBrowser.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,6 @@ export const UnsupportedBrowserComponent = ({
) : (
<H3 css={{marginBottom: 10}} data-uie-name="element-unsupported-general">
{_(unsupportedStrings.subheadBrowser, {
// eslint-disable-next-line react/display-name
strong: (...chunks: any[]) => <strong style={{fontWeight: 800}}>{chunks}</strong>,
})}
</H3>
Expand Down
3 changes: 1 addition & 2 deletions src/script/auth/component/WirelessContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,7 @@ const WirelessContainer: React.FC<Props> = ({showCookiePolicyBanner, onCookiePol
{...cookiePolicyStrings.bannerText}
values={{
newline: <br />,
// eslint-disable-next-line react/display-name
strong: ((...chunks: any[]) => <strong>{chunks}</strong>) as any,
strong: (...chunks: any[]) => <strong>{chunks}</strong>,
}}
/>
</Link>
Expand Down
11 changes: 5 additions & 6 deletions src/script/auth/module/action/AuthAction.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
*/

import {ClientType} from '@wireapp/api-client/lib/client/';
import {RecursivePartial} from '@wireapp/commons/lib/util/TypeUtil';
import {StatusCodes as HTTP_STATUS} from 'http-status-codes';

import type {APIClient} from '@wireapp/api-client';
Expand All @@ -28,7 +29,7 @@ import {AuthActionCreator} from './creator/';

import {mockStoreFactory} from '../../util/test/mockStoreFactory';

import {actionRoot} from './';
import {ActionRoot, actionRoot} from './';

describe('AuthAction', () => {
it('authenticates a user successfully', async () => {
Expand Down Expand Up @@ -129,14 +130,12 @@ describe('AuthAction', () => {
backendError.code = HTTP_STATUS.FORBIDDEN;
backendError.label = 'invalid-credentials';
backendError.message = 'Authentication failed.';
const spies = {
generateClientPayload: jasmine.createSpy().and.returnValue({}),
};

const mockedActions = {
clientAction: {
generateClientPayload: spies.generateClientPayload,
generateClientPayload: jest.fn().mockReturnValue({}),
},
};
} as RecursivePartial<ActionRoot>;
const mockedCore = {
login: () => Promise.reject(backendError),
};
Expand Down
45 changes: 45 additions & 0 deletions src/script/auth/module/action/AuthAction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ import type {DomainData} from '@wireapp/api-client/lib/account/DomainData';
import type {LoginData, RegisterData, SendLoginCode} from '@wireapp/api-client/lib/auth/';
import {VerificationActionType} from '@wireapp/api-client/lib/auth/VerificationActionType';
import {ClientType} from '@wireapp/api-client/lib/client/';
import {OAuthBody} from '@wireapp/api-client/lib/oauth/OAuthBody';
import {OAuthClient} from '@wireapp/api-client/lib/oauth/OAuthClient';
import type {TeamData} from '@wireapp/api-client/lib/team/';
import {LowDiskSpaceError} from '@wireapp/store-engine/lib/engine/error';
import {StatusCodes as HTTP_STATUS, StatusCodes} from 'http-status-codes';

Expand Down Expand Up @@ -145,6 +148,20 @@ export class AuthAction {
};
};

doPostOAuthCode = (oauthBody: OAuthBody): ThunkAction<Promise<string>> => {
return async (dispatch, getState, {apiClient}) => {
dispatch(AuthActionCreator.startSendOAuthCode());
try {
const url = await apiClient.api.oauth.postOAuthCode(oauthBody);
dispatch(AuthActionCreator.successfulSendOAuthCode());
return url;
} catch (error) {
dispatch(AuthActionCreator.failedSendOAuthCode(error));
throw error;
}
};
};

doSendTwoFactorLoginCode = (email: string): ThunkAction => {
return async (dispatch, getState, {apiClient}) => {
dispatch(AuthActionCreator.startSendTwoFactorCode());
Expand Down Expand Up @@ -185,6 +202,34 @@ export class AuthAction {
};
};

doGetTeamData = (teamId: string): ThunkAction<Promise<TeamData>> => {
return async (dispatch, getState, {apiClient}) => {
dispatch(AuthActionCreator.startFetchTeam());
try {
const teamData = await apiClient.api.teams.team.getTeam(teamId);
dispatch(AuthActionCreator.successfulFetchTeam(teamData));
return teamData;
} catch (error) {
dispatch(AuthActionCreator.failedFetchTeam(error));
throw error;
}
};
};

doGetOAuthApplication = (applicationId: string): ThunkAction<Promise<OAuthClient>> => {
return async (dispatch, getState, {apiClient}) => {
dispatch(AuthActionCreator.startFetchOAuth());
try {
const application = await apiClient.api.oauth.getClient(applicationId);
dispatch(AuthActionCreator.successfulFetchOAuth(application));
return application;
} catch (error) {
dispatch(AuthActionCreator.failedFetchOAuth(error));
throw error;
}
};
};

validateSSOCode = (code: string): ThunkAction => {
return async (dispatch, getState, {apiClient}) => {
const mapError = (error: any) => {
Expand Down
2 changes: 1 addition & 1 deletion src/script/auth/module/action/ClientAction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ export class ClientAction {
};
};

generateClientPayload = (clientType: ClientType): ClientInfo | undefined => {
private generateClientPayload = (clientType: ClientType): ClientInfo | undefined => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 🙏

if (clientType === ClientType.NONE) {
return undefined;
}
Expand Down
Loading