Skip to content

Commit

Permalink
refactor: Review repository impl and structure (#260)
Browse files Browse the repository at this point in the history
* refactor(core): file structure and unused imports

* refactor(ui): better handling of global types and toast msgs

* test(ui): fix tests after refactor

* fix(ui): next route for generating seed phrase

* refactor: rename cloud-services and move webrtc-relay

* refactor(ui): utils

* test(ui): move capacitor mocks (may not work)

* refactor: move cred server into services

* refactor: move services docker and readme back down

* refactor(ui): properly rename colorgenerator in git

* refactor: remove unused icons dir and move assets into src

* test(ui): correct mock path for colorGenerator

* build(docker): new path for cred issuance serv

* refactor: post merge fixes and remove redundant ops and toasts

* refactor(ui): remove unused paths post merge

* fix(ui): toast visibility should be triggered on toast msg change

* fix(ui): post-merge import
  • Loading branch information
iFergal authored Nov 23, 2023
1 parent 9e62585 commit d9cf5f2
Show file tree
Hide file tree
Showing 164 changed files with 460 additions and 516 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ Install capacitor [assets tool](https://capacitorjs.com/docs/guides/splash-scree
npm install @capacitor/assets --save-dev
```

Create a `assets` folder in the root directory with:
Create a `assets` folder in the `src` directory with:
```
assets/
├── icon-only.png
Expand All @@ -125,9 +125,9 @@ assets/

For iOS:
```
npx @capacitor/assets generate --ios
npx @capacitor/assets --assetPath ./src/assets generate --ios
```
For Android:
```
npx @capacitor/assets generate --android
npx @capacitor/assets --assetPath ./src/assets generate --android
```
11 changes: 1 addition & 10 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -1,18 +1,9 @@
version: "3.9"
services:
webrtc-relay:
container_name: webrtc-relay
build:
context: ./webrtc-relay
dockerfile: Dockerfile
tty: true
ports:
- "51986:51986"
restart: always
issuer-server:
container_name: issuer-server
build:
context: ./credential-issuance-server
context: ./services/credential-issuance-server
dockerfile: Dockerfile
tty: true
ports:
Expand Down
Binary file removed icons/icon-128.webp
Binary file not shown.
Binary file removed icons/icon-192.webp
Binary file not shown.
Binary file removed icons/icon-256.webp
Binary file not shown.
Binary file removed icons/icon-48.webp
Binary file not shown.
Binary file removed icons/icon-512.webp
Binary file not shown.
Binary file removed icons/icon-72.webp
Binary file not shown.
Binary file removed icons/icon-96.webp
Binary file not shown.
4 changes: 2 additions & 2 deletions cloud-services/README.md → services/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
## Cloud services
At the moment, our wallet depends on a number of cloud services:
## External services
At the moment, our wallet depends on a number of services (external to this project or developed by us) which will generally run in the cloud:
- KERIA (KERI Cloud Agent),
- AFJ Mediator
- Credential issuance server (from this repo)
Expand Down
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# ID Wallet Issuer Server
#### How to run
This server runs an Aries and Signify agent to act as an issuance server for both W3C credentials and ACDCs (KERI eco-system).
Right now, this is only used for testing purposes for the wallet - it is not meant as a full blown issuance server - hence there are no tests in this module.

### How to run (development)
1. Install dependencies (nodejs >= v18):
`npm install`
2. Run development server:
Expand All @@ -18,3 +20,5 @@
- `npm run cli:offer-credential-connection-less degree-credential-with-expiration.json`
- `npm run cli:offer-credential resident-card-with-expiration.json`
- `npm run cli:offer-credential summit-access-pass.json`

The CLI may also be used locally to point at a remotely deployed server by setting the `ENDPOINT` environment variable. (default is `http://1237.0.0.1:3001`)
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
13 changes: 7 additions & 6 deletions src/core/agent/agent.types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { BaseEvent, JsonCredential } from "@aries-framework/core";
import { IdentifierMetadataRecordProps } from "./modules";
import { CredentialMetadataRecordProps } from "./modules/generalStorage/repositories/credentialMetadataRecord.types";

enum IdentifierType {
Expand Down Expand Up @@ -113,15 +112,16 @@ interface CredentialDetails extends CredentialShortDetails {
proofValue?: string;
}

enum CredentialType {
UNIVERSITY_DEGREE_CREDENTIAL = "UniversityDegreeCredential",
ACCESS_PASS_CREDENTIAL = "AccessPassCredential",
PERMANENT_RESIDENT_CARD = "PermanentResidentCard",
}

type GetIdentifierResult =
| { type: IdentifierType.KERI; result: KERIDetails }
| { type: IdentifierType.KEY; result: DIDDetails };

type UpdateIdentityMetadata = Omit<
Partial<IdentifierMetadataRecordProps>,
"id" | "isArchived" | "name" | "method" | "createdAt"
>;

enum ConnectionKeriEventTypes {
ConnectionKeriStateChanged = "ConnectionKeriStateChanged",
}
Expand All @@ -141,6 +141,7 @@ export {
ConnectionHistoryType,
MiscRecordId,
ConnectionType,
CredentialType,
ConnectionKeriEventTypes,
};
export type {
Expand Down
1 change: 1 addition & 0 deletions src/core/agent/documentLoader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const DOCUMENTS: { [key: string]: any } = {
"https://w3id.org/did/v1": DID_V1,
};

// Caches documents locally in the build in case the W3C sites are down
function documentLoader(agentContext: AgentContext): DocumentLoader {
const didResolver =
agentContext.dependencyManager.resolve(DidResolverService);
Expand Down
2 changes: 2 additions & 0 deletions src/core/agent/modules/ionicstorage/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
For now this is used only on the browser for development and is never used in the final build (mobile -> SQLite).
With encryption at rest and better key management in the browser, this __could__ be used for a browser extension but is not there right now and is not a target platform for us.
7 changes: 5 additions & 2 deletions src/core/agent/services/credentialService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,17 @@ import {
W3cJsonLdVerifiableCredential,
JsonObject,
} from "@aries-framework/core";
import { CredentialDetails, CredentialShortDetails } from "../agent.types";
import {
CredentialDetails,
CredentialShortDetails,
CredentialType,
} from "../agent.types";
import { CredentialMetadataRecord } from "../modules";
import { AgentService } from "./agentService";
import {
CredentialMetadataRecordProps,
CredentialMetadataRecordStatus,
} from "../modules/generalStorage/repositories/credentialMetadataRecord.types";
import { CredentialType } from "../../../ui/constants/dictionary";

class CredentialService extends AgentService {
static readonly CREDENTIAL_MISSING_METADATA_ERROR_MSG =
Expand Down
2 changes: 2 additions & 0 deletions src/core/agent/transports/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
DIDComm via LibP2P can be achieved with these transports - this is a proof of concept and not currently enabled in the wallet.
When we bring P2P into the wallet it will come with much more testing.
1 change: 1 addition & 0 deletions src/core/storage/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from "./secureStorage";
export * from "./preferences";
34 changes: 17 additions & 17 deletions src/core/storage/preferences/preferencesStorage.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import {
import { PreferencesStorage } from "./preferencesStorage";
import { PreferencesStorageItem } from "./preferencesStorage.type";

const EXISTING_KEY = "keythatexists";
const NON_EXISTING_KEY = "keythatdoesnotexist";
const EXISTING_VALUE: PreferencesStorageItem = { data: "test" };
const existingKey = "keythatexists";
const nonExistingKey = "keythatdoesnotexist";
const existingValue: PreferencesStorageItem = { data: "test" };

describe("Preferences Storage", () => {
afterEach(jest.clearAllMocks);
Expand All @@ -17,44 +17,44 @@ describe("Preferences Storage", () => {
.fn()
.mockImplementation(
async (data: SetOptions): Promise<GetResult | null> => {
if (data.key === EXISTING_KEY) {
return { value: JSON.stringify(EXISTING_VALUE) };
if (data.key === existingKey) {
return { value: JSON.stringify(existingValue) };
}
return null;
}
);
expect(await PreferencesStorage.get(EXISTING_KEY)).toEqual(EXISTING_VALUE);
expect(Preferences.get).toHaveBeenCalledWith({ key: EXISTING_KEY });
await expect(PreferencesStorage.get(NON_EXISTING_KEY)).rejects.toThrow(
`${PreferencesStorage.KEY_NOT_FOUND} ${NON_EXISTING_KEY}`
expect(await PreferencesStorage.get(existingKey)).toEqual(existingValue);
expect(Preferences.get).toHaveBeenCalledWith({ key: existingKey });
await expect(PreferencesStorage.get(nonExistingKey)).rejects.toThrow(
`${PreferencesStorage.KEY_NOT_FOUND} ${nonExistingKey}`
);
});

test("sets an item correctly", async () => {
Preferences.set = jest
.fn()
.mockImplementation(async (data: SetOptions): Promise<void> => {
expect(data.key).toBe(EXISTING_KEY);
expect(data.value).toBe(JSON.stringify(EXISTING_VALUE));
expect(data.key).toBe(existingKey);
expect(data.value).toBe(JSON.stringify(existingValue));
});

await PreferencesStorage.set(EXISTING_KEY, EXISTING_VALUE);
await PreferencesStorage.set(existingKey, existingValue);

expect(Preferences.set).toHaveBeenCalledWith({
key: EXISTING_KEY,
value: JSON.stringify(EXISTING_VALUE),
key: existingKey,
value: JSON.stringify(existingValue),
});
});

test("deletes an item correctly", async () => {
Preferences.remove = jest
.fn()
.mockImplementation(async (data: RemoveOptions) => {
expect(data.key).toBe(EXISTING_KEY);
expect(data.key).toBe(existingKey);
});

await PreferencesStorage.remove(EXISTING_KEY);
await PreferencesStorage.remove(existingKey);

expect(Preferences.remove).toHaveBeenCalledWith({ key: EXISTING_KEY });
expect(Preferences.remove).toHaveBeenCalledWith({ key: existingKey });
});
});
2 changes: 0 additions & 2 deletions src/core/storage/preferences/preferencesStorage.type.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { FavouriteIdentity } from "../../../store/reducers/identitiesCache/identitiesCache.types";

interface PreferencesStorageItem {
[key: string]: string | number | boolean | Array<any>;
}
Expand Down
1 change: 1 addition & 0 deletions src/core/storage/secureStorage/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./secureStorage";
File renamed without changes.
File renamed without changes.
9 changes: 5 additions & 4 deletions src/routes/backRoute/backRoute.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ import {
} from "./backRoute";
import { RoutePath } from "../index";
import { setAuthentication } from "../../store/reducers/stateCache";
import { FIFTEEN_WORDS_BIT_LENGTH } from "../../constants/appConstants";
import { FIFTEEN_WORDS_BIT_LENGTH } from "../../ui/globals/constants";
import { OperationType } from "../../ui/globals/types";

jest.mock("../../store/reducers/stateCache", () => ({
removeCurrentRoute: jest.fn(),
Expand Down Expand Up @@ -41,7 +42,7 @@ describe("getBackRoute", () => {
loggedIn: false,
time: 0,
},
currentOperation: "",
currentOperation: OperationType.IDLE,
queueConnectionCredentialRequest: {
isProcessing: false,
queues: [],
Expand Down Expand Up @@ -121,7 +122,7 @@ describe("getBackRoute", () => {
passwordIsSet: false,
passwordIsSkipped: true,
},
currentOperation: "",
currentOperation: OperationType.IDLE,
queueConnectionCredentialRequest: {
isProcessing: false,
queues: [],
Expand Down Expand Up @@ -196,7 +197,7 @@ describe("getPreviousRoute", () => {
loggedIn: false,
time: 0,
},
currentOperation: "",
currentOperation: OperationType.IDLE,
queueConnectionCredentialRequest: {
isProcessing: false,
queues: [],
Expand Down
16 changes: 5 additions & 11 deletions src/routes/nextRoute/nextRoute.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import {
import { RootState } from "../../store";
import { RoutePath } from "../index";
import { setAuthentication } from "../../store/reducers/stateCache";
import { FIFTEEN_WORDS_BIT_LENGTH } from "../../constants/appConstants";
import { FIFTEEN_WORDS_BIT_LENGTH } from "../../ui/globals/constants";
import { DataProps } from "./nextRoute.types";
import { TabsRoutePath } from "../paths";
import { OperationType } from "../../ui/globals/types";

describe("NextRoute", () => {
let localStorageMock: any;
Expand All @@ -32,7 +32,7 @@ describe("NextRoute", () => {
passwordIsSet: false,
passwordIsSkipped: true,
},
currentOperation: "",
currentOperation: OperationType.IDLE,
queueConnectionCredentialRequest: {
isProcessing: false,
queues: [],
Expand Down Expand Up @@ -112,13 +112,7 @@ describe("NextRoute", () => {
});

test("should return correct route for /verifyseedphrase", () => {
const data = {
store: storeMock,
state: {
currentOperation: "",
},
};
const result = getNextVerifySeedPhraseRoute(data);
const result = getNextVerifySeedPhraseRoute();

expect(result).toEqual({
pathname: RoutePath.CREATE_PASSWORD,
Expand All @@ -139,7 +133,7 @@ describe("getNextRoute", () => {
passwordIsSet: false,
passwordIsSkipped: true,
},
currentOperation: "",
currentOperation: OperationType.IDLE,
queueConnectionCredentialRequest: {
isProcessing: false,
queues: [],
Expand Down
21 changes: 10 additions & 11 deletions src/routes/nextRoute/nextRoute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
} from "../../store/reducers/seedPhraseCache";
import { DataProps, StoreState } from "./nextRoute.types";
import { RoutePath, TabsRoutePath } from "../paths";
import { toastState } from "../../ui/constants/dictionary";
import { ToastMsgType } from "../../ui/globals/types";

const getNextRootRoute = (store: StoreState) => {
const isInitialized = store.stateCache.initialized;
Expand Down Expand Up @@ -40,10 +40,10 @@ const getNextRootRoute = (store: StoreState) => {

const getNextOnboardingRoute = (data: DataProps) => {
let path;
if (!data.store.stateCache.authentication.passcodeIsSet) {
path = RoutePath.SET_PASSCODE;
} else {
if (data.store.stateCache.authentication.passcodeIsSet) {
path = RoutePath.GENERATE_SEED_PHRASE;
} else {
path = RoutePath.SET_PASSCODE;
}

return { pathname: path };
Expand Down Expand Up @@ -98,9 +98,8 @@ const getNextGenerateSeedPhraseRoute = () => {
return { pathname: RoutePath.VERIFY_SEED_PHRASE };
};

const getNextVerifySeedPhraseRoute = (data: DataProps) => {
const nextPath: string = RoutePath.CREATE_PASSWORD;

const getNextVerifySeedPhraseRoute = () => {
const nextPath = RoutePath.CREATE_PASSWORD;
return { pathname: nextPath };
};

Expand Down Expand Up @@ -128,11 +127,11 @@ const updateStoreAfterCreatePassword = (data: DataProps) => {
};

const getNextScanRoute = (data: DataProps) => {
const currentOperation = data?.state?.currentOperation;
const currentToastMsg = data?.state?.toastMsg;
let path;
if (
currentOperation === toastState.connectionRequestPending ||
currentOperation === toastState.credentialRequestPending
currentToastMsg === ToastMsgType.CONNECTION_REQUEST_PENDING ||
currentToastMsg === ToastMsgType.CREDENTIAL_REQUEST_PENDING
) {
path = TabsRoutePath.CREDS;
}
Expand Down Expand Up @@ -174,7 +173,7 @@ const nextRoute: Record<string, any> = {
updateRedux: [updateStoreSetSeedPhrase],
},
[RoutePath.VERIFY_SEED_PHRASE]: {
nextPath: (data: DataProps) => getNextVerifySeedPhraseRoute(data),
nextPath: (data: DataProps) => getNextVerifySeedPhraseRoute(),
updateRedux: [updateStoreAfterVerifySeedPhraseRoute, clearSeedPhraseCache],
},
[RoutePath.CREATE_PASSWORD]: {
Expand Down
2 changes: 1 addition & 1 deletion src/store/reducers/seedPhraseCache/seedPhraseCache.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
setSeedPhraseCache,
} from "./seedPhraseCache";
import { RootState } from "../../index";
import { FIFTEEN_WORDS_BIT_LENGTH } from "../../../constants/appConstants";
import { FIFTEEN_WORDS_BIT_LENGTH } from "../../../ui/globals/constants";

describe("SeedPhraseCache", () => {
test("should return the initial state on first run", () => {
Expand Down
2 changes: 1 addition & 1 deletion src/store/reducers/seedPhraseCache/seedPhraseCache.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
import { RootState } from "../../index";
import { SeedPhraseCacheProps } from "./seedPhraseCache.types";
import { FIFTEEN_WORDS_BIT_LENGTH } from "../../../constants/appConstants";
import { FIFTEEN_WORDS_BIT_LENGTH } from "../../../ui/globals/constants";
const initialState: SeedPhraseCacheProps = {
seedPhrase160: "",
seedPhrase256: "",
Expand Down
Loading

0 comments on commit d9cf5f2

Please sign in to comment.