-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: enable secret recovery request.
- Loading branch information
1 parent
cea09c3
commit 4592751
Showing
8 changed files
with
186 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,30 +1,67 @@ | ||
import { ClosedIdentityLoc } from "@logion/client"; | ||
import { ClosedIdentityLoc, CreateSecretRecoveryRequest } from "@logion/client"; | ||
import { State } from "./Utils"; | ||
import { UUID } from "@logion/node-api"; | ||
|
||
const secretToKeep = "Key"; | ||
|
||
export async function recoverableSecrets(state: State) { | ||
const requesterIdentityLocId = await addSecrets(state); | ||
await createRecoveryRequest(state, requesterIdentityLocId); | ||
} | ||
|
||
async function addSecrets(state: State): Promise<UUID> { | ||
const { requesterAccount } = state; | ||
|
||
const client = state.client.withCurrentAccount(requesterAccount); | ||
let locsState = await client.locsState(); | ||
|
||
let closedIdentityLoc = locsState.closedLocs.Identity[0] as ClosedIdentityLoc; | ||
expect(closedIdentityLoc).toBeInstanceOf(ClosedIdentityLoc); | ||
const name = "Key"; | ||
const value = "Encrypted key"; | ||
|
||
closedIdentityLoc = await closedIdentityLoc.addSecret({ | ||
name, | ||
name: secretToKeep, | ||
value, | ||
}); | ||
const secretToRemove = "secret-to-remove"; | ||
closedIdentityLoc = await closedIdentityLoc.addSecret({ | ||
name: secretToRemove, | ||
value, | ||
}); | ||
|
||
expect(closedIdentityLoc).toBeInstanceOf(ClosedIdentityLoc); | ||
|
||
let data = closedIdentityLoc.data(); | ||
expect(data.secrets.length).toBe(2); | ||
|
||
closedIdentityLoc = await closedIdentityLoc.removeSecret(secretToRemove); | ||
|
||
data = closedIdentityLoc.data(); | ||
expect(data.secrets.length).toBe(1); | ||
expect(data.secrets[0].name).toBe(name); | ||
expect(data.secrets[0].name).toBe(secretToKeep); | ||
expect(data.secrets[0].value).toBe(value); | ||
|
||
closedIdentityLoc = await closedIdentityLoc.removeSecret(name); | ||
return closedIdentityLoc.locId; | ||
} | ||
|
||
data = closedIdentityLoc.data(); | ||
expect(data.secrets.length).toBe(0); | ||
async function createRecoveryRequest(state: State, requesterIdentityLocId: UUID) { | ||
const request: CreateSecretRecoveryRequest = { | ||
requesterIdentityLocId, | ||
secretName: secretToKeep, | ||
challenge: "my-personal-challenge", | ||
userIdentity: { | ||
email: "[email protected]", | ||
firstName: "John", | ||
lastName: "Doe", | ||
phoneNumber: "+1234", | ||
}, | ||
userPostalAddress: { | ||
line1: "Line1", | ||
line2: "Line2", | ||
postalCode: "PostalCode", | ||
city: "City", | ||
country: "Country", | ||
} | ||
} | ||
await state.client.secretRecovery.createSecretRecoveryRequest(request); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
{ | ||
"name": "@logion/client", | ||
"version": "0.45.0-7", | ||
"version": "0.45.0-8", | ||
"description": "logion SDK for client applications", | ||
"main": "dist/index.js", | ||
"packageManager": "[email protected]", | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import { SharedState } from "./SharedClient.js"; | ||
import { CreateSecretRecoveryRequest, SecretRecoveryClient } from "./SecretRecoveryClient.js"; | ||
|
||
export class SecretRecoveryApi { | ||
|
||
constructor(args: { sharedState: SharedState }) { | ||
this.client = new SecretRecoveryClient(args); | ||
} | ||
|
||
private readonly client: SecretRecoveryClient; | ||
|
||
async createSecretRecoveryRequest(params: CreateSecretRecoveryRequest): Promise<void> { | ||
await this.client.createSecretRecoveryRequest(params); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import { UserIdentity, PostalAddress } from "./Types"; | ||
import { LocMultiClient, FetchParameters } from "./LocClient.js"; | ||
import { requireDefined } from "./assertions.js"; | ||
import { SharedState } from "./SharedClient.js"; | ||
import { AxiosInstance } from "axios"; | ||
import { UUID } from "@logion/node-api"; | ||
import { newBackendError } from "./Error.js"; | ||
|
||
export interface CreateSecretRecoveryRequest { | ||
requesterIdentityLocId: UUID; | ||
secretName: string; | ||
challenge: string; | ||
userIdentity: UserIdentity; | ||
userPostalAddress: PostalAddress; | ||
} | ||
|
||
export class SecretRecoveryClient { | ||
|
||
constructor(args: { sharedState: SharedState }) { | ||
this.sharedState = args.sharedState; | ||
} | ||
|
||
private sharedState: SharedState; | ||
|
||
async createSecretRecoveryRequest(params: CreateSecretRecoveryRequest): Promise<void> { | ||
const { secretName, challenge, userIdentity, userPostalAddress, requesterIdentityLocId } = params; | ||
const axios = await this.backend({ locId: requesterIdentityLocId }); | ||
try { | ||
await axios.post("/api/secret-recovery", { | ||
requesterIdentityLocId: requesterIdentityLocId.toString(), | ||
secretName, | ||
challenge, | ||
userIdentity, | ||
userPostalAddress, | ||
}); | ||
} catch (e) { | ||
throw newBackendError(e); | ||
} | ||
} | ||
|
||
private async backend(params: FetchParameters): Promise<AxiosInstance> { | ||
const loc = await LocMultiClient.getLoc({ | ||
...params, | ||
api: this.sharedState.nodeApi, | ||
}); | ||
const legalOfficer = requireDefined(this.sharedState.legalOfficers.find(lo => lo.account.equals(loc.owner))); | ||
return legalOfficer.buildAxiosToNode(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import { LogionClient, LegalOfficerClass, PostalAddress, UserIdentity, } from "../src/index.js"; | ||
import { buildTestConfig, LOGION_CLIENT_CONFIG, ALICE } from "./Utils.js"; | ||
import { buildLocAndRequest } from "./LocUtils.js"; | ||
import { UUID } from "@logion/node-api"; | ||
import { Mock, It, Times } from "moq.ts"; | ||
import { AxiosInstance, AxiosResponse } from "axios"; | ||
|
||
describe("SecretRecovery", () => { | ||
|
||
it("requests a Secret recovery", async () => { | ||
|
||
const identityLoc = buildLocAndRequest(ALICE.account, "CLOSED", "Identity"); | ||
const locId = new UUID(identityLoc.request.id); | ||
const axios = new Mock<AxiosInstance>(); | ||
|
||
const config = buildTestConfig(testConfigFactory => { | ||
testConfigFactory.setupDefaultNetworkState(); | ||
const axiosFactory = testConfigFactory.setupAxiosFactoryMock(); | ||
axiosFactory.setup(instance => instance.buildAxiosInstance(It.IsAny<string>(), It.IsAny())) | ||
.returns(axios.object()); | ||
setupBackend(axios, locId); | ||
const nodeApi = testConfigFactory.setupNodeApiMock(LOGION_CLIENT_CONFIG); | ||
const directoryClient = testConfigFactory.setupDirectoryClientMock(LOGION_CLIENT_CONFIG); | ||
|
||
directoryClient.setup(instance => instance.getLegalOfficers()).returns(Promise.resolve([ | ||
new LegalOfficerClass({ | ||
legalOfficer: ALICE, | ||
axiosFactory: axiosFactory.object(), | ||
}) | ||
])); | ||
|
||
nodeApi.setup(instance => instance.queries.getLegalOfficerCase(locId)) | ||
.returns(Promise.resolve(identityLoc.loc)); | ||
}) | ||
|
||
const client = await LogionClient.create(config); | ||
await client.secretRecovery.createSecretRecoveryRequest({ | ||
requesterIdentityLocId: locId, | ||
secretName: "secret-name", | ||
challenge: "my-personal-challenge", | ||
userIdentity: {} as UserIdentity, | ||
userPostalAddress: {} as PostalAddress, | ||
}) | ||
axios.verify(instance => instance.post("/api/secret-recovery", It.IsAny()), Times.Once()); | ||
}) | ||
}) | ||
|
||
function setupBackend(axios: Mock<AxiosInstance>, locId: UUID) { | ||
const response = new Mock<AxiosResponse<any>>(); | ||
axios.setup(instance => instance.post("/api/secret-recovery", It.Is<{ requesterIdentityLocId: string, secretName: string, challenge: string }>(body => | ||
body.requesterIdentityLocId === locId.toString() && | ||
body.secretName === "secret-name" && | ||
body.challenge === "my-personal-challenge", | ||
))) | ||
.returns(Promise.resolve(response.object())) | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters