Skip to content
This repository was archived by the owner on Mar 4, 2025. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
fe01955
feat: add local mode for client logs/metrics
Jan 24, 2024
a8b40df
chore: upgrading to amplify v6
mnischay Feb 8, 2024
c00b899
Revert "chore: upgrading to amplify v6"
Feb 16, 2024
352f492
feat: edge app kit client config
Mar 1, 2024
75a0602
feat: add 401 exception handling for edge
Feb 29, 2024
d32fb60
fix: static edge endpoint on edge mode
chejimmy Mar 1, 2024
c68c8d3
chore(deps): bump the tanstack group with 2 updates
dependabot[bot] Mar 1, 2024
9050b0c
chore(deps): bump @cloudscape-design/collection-hooks
dependabot[bot] Mar 1, 2024
c040745
chore(deps-dev): bump @types/react from 18.2.57 to 18.2.61
dependabot[bot] Mar 1, 2024
1643a37
chore(deps-dev): bump babel-plugin-formatjs from 10.5.12 to 10.5.13
dependabot[bot] Mar 4, 2024
f9c502c
chore(deps): bump aws-cdk-lib from 2.130.0 to 2.131.0
dependabot[bot] Mar 4, 2024
675ac3a
chore(deps): bump @fastify/view from 8.2.0 to 9.0.0
dependabot[bot] Mar 4, 2024
4ee4388
chore(deps): bump cytoscape from 3.27.0 to 3.28.1
dependabot[bot] Mar 4, 2024
42685f3
chore(deps): bump vite from 5.0.12 to 5.1.5
dependabot[bot] Mar 4, 2024
8476245
feat: support edge logout
Mar 11, 2024
f016112
feat: add edge as a deployment option
Mar 13, 2024
a2bd598
chore: increase timeout limit for playwright tests (#2058)
ssjagad Mar 22, 2024
dc18aff
chore: bump iot-app-kit v10.1.0 (#2057)
ssjagad Mar 22, 2024
7228f99
fix: update migration logic to match updated dashboard definition
Mar 26, 2024
43c001c
fix: viewport should default to 5 mins option
ssjagad Mar 27, 2024
e1918e7
chore: downgrade iot-appkit to 10.0.0 (#2075)
ssjagad Mar 28, 2024
0e71d25
chore: upgrade appkit to 10.2.0 (#2077)
ssjagad Mar 29, 2024
af3724c
chore: upgrade amplify
jmbuss Mar 27, 2024
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
2 changes: 1 addition & 1 deletion .github/workflows/deployment-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ jobs:

test:
needs: [deploy]
timeout-minutes: 15
timeout-minutes: 30
runs-on: ubuntu-latest

steps:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/playwright.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ on:

jobs:
playwright:
timeout-minutes: 15
timeout-minutes: 30
runs-on: ubuntu-latest

steps:
Expand Down
2 changes: 2 additions & 0 deletions apps/client/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
<meta name="awsSecretAccessKey" content="{{clientAwsSecretAccessKey}}" />
<meta name="awsSessionToken" content="{{clientAwsSessionToken}}" />
<meta name="cognitoEndpoint" content="{{cognitoEndpoint}}" />
<meta name="edgeEndpoint" content="{{edgeEndpoint}}" />
<meta name="identityPoolId" content="{{identityPoolId}}" />
<meta name="region" content="{{region}}" />
<meta name="userPoolWebClientId" content="{{userPoolWebClientId}}" />
Expand All @@ -17,6 +18,7 @@
<meta name="logMode" content="{{logMode}}" />
<meta name="metricsMode" content="{{metricsMode}}" />
<meta name="authMode" content="{{authMode}}" />
<meta name="ssoProvider" content="{{ssoProvider}}" />

<title>IoT Application</title>
</head>
Expand Down
22 changes: 11 additions & 11 deletions apps/client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,23 +21,23 @@
"test:ui": "vitest --ui"
},
"dependencies": {
"@aws-amplify/ui-react": "^5.3.2",
"@aws-amplify/ui-react": "^6.1.6",
"@aws-sdk/client-cloudwatch": "3.515.0",
"@aws-sdk/client-cloudwatch-logs": "3.515.0",
"@aws-sdk/client-iot-events": "3.515.0",
"@aws-sdk/client-iotsitewise": "3.515.0",
"@aws-sdk/credential-providers": "3.515.0",
"@cloudscape-design/collection-hooks": "^1.0.36",
"@cloudscape-design/collection-hooks": "^1.0.37",
"@cloudscape-design/component-toolkit": "^1.0.0-beta.38",
"@cloudscape-design/components": "^3.0.518",
"@cloudscape-design/design-tokens": "3.0.34",
"@cloudscape-design/global-styles": "^1.0.23",
"@iot-app-kit/core": "10.0.0",
"@iot-app-kit/dashboard": "10.0.0",
"@tanstack/react-query": "^5.22.2",
"aws-amplify": "^5.3.11",
"@iot-app-kit/core": "10.2.0",
"@iot-app-kit/dashboard": "10.2.0",
"@tanstack/react-query": "^5.24.1",
"aws-amplify": "^6.0.26",
"axios": "^1.6.7",
"cytoscape": "^3.27.0",
"cytoscape": "^3.28.1",
"jotai": "^2.6.4",
"nanoid": "3.1.31",
"react": "^18.2.0",
Expand All @@ -49,7 +49,7 @@
"react-use": "^17.4.2",
"tiny-invariant": "^1.3.1",
"uuid": "^9.0.1",
"vite": "^5.0.12",
"vite": "^5.1.5",
"web-vitals": "^3.5.0"
},
"devDependencies": {
Expand All @@ -59,20 +59,20 @@
"@hookform/devtools": "^4.3.1",
"@originjs/vite-plugin-federation": "^1.3.3",
"@tanstack/eslint-plugin-query": "^5.20.1",
"@tanstack/react-query-devtools": "^5.24.0",
"@tanstack/react-query-devtools": "^5.24.1",
"@testing-library/jest-dom": "^6.4.2",
"@testing-library/react": "^14.1.0",
"@testing-library/react-hooks": "^8.0.1",
"@testing-library/user-event": "^14.5.2",
"@types/react": "^18.2.57",
"@types/react": "^18.2.61",
"@types/react-dom": "^18.2.19",
"@types/uuid": "^9.0.8",
"@vitejs/plugin-react": "^4.2.1",
"@vitest/coverage-v8": "^0.34.4",
"@vitest/ui": "^1.1.1",
"aws-sdk-client-mock": "^3.0.0",
"aws-sdk-client-mock-jest": "^3.0.0",
"babel-plugin-formatjs": "^10.5.12",
"babel-plugin-formatjs": "^10.5.13",
"customize-cra": "^1.0.0",
"eslint-config-custom": "*",
"eslint-plugin-formatjs": "^4.11.1",
Expand Down
10 changes: 10 additions & 0 deletions apps/client/src/auth/auth-service.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ export interface AuthService {
*/
get awsRegion(): string;

/**
* Sets the AWS Region.
*/
setAwsRegion(region: string): void;

/**
* Returns the user's session token.
* @return - the user's session token
Expand All @@ -31,4 +36,9 @@ export interface AuthService {
* @param callback the callback function to call when application is signed-in
*/
onSignedIn(callback: () => unknown): void;

// TODO: Refactor interface to only include shared methods
getEdgeEndpoint?(): string;

setEdgeEndpoint?(endpoint: string): void;
}
17 changes: 17 additions & 0 deletions apps/client/src/auth/auth-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,30 @@ class ClientAuthService {
return this.authService.awsRegion;
}

setAwsRegion(region: string) {
this.authService.setAwsRegion(region);
}

getToken() {
return this.authService.getToken();
}

onSignedIn(callback: () => unknown) {
return this.authService.onSignedIn(callback);
}

setEdgeEndpoint(endpoint: string) {
if (this.authService.setEdgeEndpoint) {
this.authService.setEdgeEndpoint(endpoint);
}
}

getEdgeEndpoint() {
if (this.authService.getEdgeEndpoint) {
return this.authService.getEdgeEndpoint();
}
return '';
}
}

export const authService = new ClientAuthService();
31 changes: 23 additions & 8 deletions apps/client/src/auth/cognito-auth-service.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,44 @@
import { Auth, Hub } from 'aws-amplify';
import { fetchAuthSession, getCurrentUser } from 'aws-amplify/auth';
import { Hub } from 'aws-amplify/utils';
import { AuthService } from './auth-service.interface';
import { type AwsCredentialIdentity } from '@smithy/types';

export class CognitoAuthService implements AuthService {
private credentials?: AwsCredentialIdentity;
public region?: string;

setAwsCredentials(credentials: AwsCredentialIdentity) {
this.credentials = credentials;
}

getAwsCredentials() {
async getAwsCredentials() {
if (this.credentials != null) {
return Promise.resolve(this.credentials);
}

return Auth.currentCredentials();
const session = await fetchAuthSession();
if (!session.credentials) {
throw new Error();
}

return Promise.resolve(session.credentials as AwsCredentialIdentity);
}

setAwsRegion(region: string) {
this.region = region;
}

get awsRegion() {
return Auth.configure().region ?? 'us-west-2';
return this.region ?? 'us-west-2';
}

async getToken() {
const session = await Auth.currentSession();
return session.getAccessToken().getJwtToken();
const session = await fetchAuthSession();

if (!session.tokens?.accessToken) {
throw new Error();
}
return session.tokens.accessToken.toString();
}

/**
Expand All @@ -37,15 +52,15 @@ export class CognitoAuthService implements AuthService {
*/
try {
// Check for initial authentication state
await Auth.currentAuthenticatedUser();
await getCurrentUser();
callback();
} catch (e) {
// NOOP; not yet authenticated;
}

// Listen for sign-in events
Hub.listen('auth', (capsule) => {
if (capsule.payload.event === 'signIn') {
if (capsule.payload.event === 'signedIn') {
callback();
}
});
Expand Down
12 changes: 12 additions & 0 deletions apps/client/src/auth/edge-auth-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,15 @@ export class EdgeAuthService implements AuthService {
accessKeyId: '',
secretAccessKey: '',
};
private edgeEndpoint = '0.0.0.0';

setEdgeEndpoint(endpoint: string) {
this.edgeEndpoint = endpoint;
}

getEdgeEndpoint() {
return this.edgeEndpoint;
}

setAwsCredentials(credentials: AwsCredentialIdentity) {
this.credentials = credentials;
Expand All @@ -20,6 +29,9 @@ export class EdgeAuthService implements AuthService {
return this.region;
}

// noop because region is edge
setAwsRegion() {}

getToken() {
if (this.credentials.sessionToken) {
return Promise.resolve(this.credentials.sessionToken);
Expand Down
19 changes: 19 additions & 0 deletions apps/client/src/auth/sso-login-footer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import React from 'react';
import Button from '@cloudscape-design/components/button';

import { signInWithRedirect, SignInWithRedirectInput } from 'aws-amplify/auth';

const amplifyPaddingVariable = 'var(--amplify-components-authenticator-form-padding)';
const formStyles: React.CSSProperties = {
textAlign: 'center',
padding: `0 ${amplifyPaddingVariable} ${amplifyPaddingVariable} ${amplifyPaddingVariable}`
};

export const SSOLogin = ({ input, text }: { input?: SignInWithRedirectInput; text: string; }) => (
<div style={formStyles}>
<Button
variant="link"
onClick={() => signInWithRedirect(input)}
>{text}</Button>
</div>
);
1 change: 1 addition & 0 deletions apps/client/src/constants/format.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ export const ROOT_INDEX_PAGE_FORMAT: Format = 'default';
export const DASHBOARDS_INDEX_PAGE_FORMAT: Format = 'table';
export const CREATE_DASHBOARD_PAGE_FORMAT: Format = 'form';
export const DASHBOARD_PAGE_FORMAT: Format = 'default';
export const EDGE_LOGIN_PAGE_FORMAT: Format = 'form';
1 change: 1 addition & 0 deletions apps/client/src/constants/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export const DASHBOARD_PATH = ':dashboardId';
export const ROOT_HREF = '/';
export const DASHBOARDS_HREF = '/dashboards';
export const CREATE_DASHBOARD_HREF = '/dashboards/create';
export const EDGE_LOGIN_HREF = '/edge-login';

export const DEFAULT_CONTENT_DENSITY: ContentDensity = 'comfortable';
export const CONTENT_DENSITY_KEY = 'content-density';
4 changes: 3 additions & 1 deletion apps/client/src/helpers/meta-tags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ export const extractedMetaTags = (
awsSecretAccessKey: '',
awsSessionToken: '',
applicationName: '',
authenticationFlowType: '',
authenticationFlowType: 'USER_PASSWORD_AUTH',
cognitoEndpoint: '',
edgeEndpoint: '',
identityPoolId: '',
region: '',
userPoolId: '',
Expand All @@ -18,6 +19,7 @@ export const extractedMetaTags = (
metricsMode: '',
domainName: '',
authMode: '',
ssoProvider: '',
};

metaElements.forEach(
Expand Down
25 changes: 25 additions & 0 deletions apps/client/src/helpers/strings/is-string-with-value.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
const isString = (value: unknown): value is string => {
return typeof value === 'string';
};

export const isStringWithValue = (value: unknown): value is string => {
return isString(value) && value !== '';
};

if (import.meta.vitest) {
it('returns true for string with value', () => {
expect(isStringWithValue('abc')).toBe(true);
});

it('returns false for string with no value', () => {
expect(isStringWithValue('')).toBe(false);
});

it('returns false for non-string value', () => {
expect(isStringWithValue({})).toBe(false);
});

it('returns false for undefined value', () => {
expect(isStringWithValue(undefined)).toBe(false);
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,8 @@ import { renderHook } from '~/helpers/tests/testing-library';
import { useDetect401Unauthorized } from './use-detect-401-unauthorized';

const signOutMock = vi.fn<[], unknown>();
vi.mock('aws-amplify', () => ({
Auth: {
signOut: () => signOutMock(),
},
vi.mock('aws-amplify/auth', () => ({
signOut: () => signOutMock(),
}));

describe('test', () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useEffect } from 'react';
import { Auth } from 'aws-amplify';
import { signOut } from 'aws-amplify/auth';

export function useDetect401Unauthorized() {
useEffect(() => {
Expand All @@ -19,6 +19,6 @@ export function useDetect401Unauthorized() {

function handleServiceWorkerMessage(event: MessageEvent<{ type?: string }>) {
if (event.data.type === '401_UNAUTHORIZED') {
void Auth.signOut();
void signOut();
}
}
Loading