timesafari
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

220 lines
6.0 KiB

<template>
<QuickNav />
<!-- CONTENT -->
<section id="Content" class="p-6 pb-24 max-w-3xl mx-auto">
<!-- Breadcrumb -->
<div id="ViewBreadcrumb" class="mb-8">
<h1 class="text-lg text-center font-light relative px-7">
<!-- Back -->
<button
class="text-lg text-center px-2 py-1 absolute -left-2 -top-1"
@click="$router.back()"
>
<font-awesome icon="chevron-left" class="fa-fw" />
</button>
Raw Claim
</h1>
</div>
<div class="flex">
<textarea v-model="claimStr" rows="20" class="border-2 w-full"></textarea>
</div>
<button
class="block w-full text-center text-lg font-bold uppercase bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-2 py-3 rounded-md"
@click="submitClaim()"
>
Sign &amp; Send
</button>
</section>
</template>
<script lang="ts">
import { Component, Vue } from "vue-facing-decorator";
import { AxiosInstance } from "axios";
import QuickNav from "../components/QuickNav.vue";
import { NotificationIface } from "../constants/app";
import { logConsoleAndDb, retrieveSettingsForActiveAccount } from "../db/index";
import * as serverUtil from "../libs/endorserServer";
import * as libsUtil from "../libs/util";
import { errorStringForLog } from "../libs/endorserServer";
import { Router, RouteLocationNormalizedLoaded } from "vue-router";
import { logger } from "../utils/logger";
/**
* View component for adding or editing raw claim data
* Allows direct JSON editing of claim data with validation and submission
*/
@Component({
components: { QuickNav },
})
export default class ClaimAddRawView extends Vue {
$notify!: (notification: NotificationIface, timeout?: number) => void;
$route!: RouteLocationNormalizedLoaded;
$router!: Router;
axios!: AxiosInstance;
accountIdentityStr: string = "null";
activeDid = "";
apiServer = "";
claimStr = "";
/**
* Lifecycle hook that initializes the view
* Workflow:
* 1. Retrieves active DID and API server from settings
* 2. Checks for existing claim data from query params:
* - If "claim" param exists: Parses and formats JSON
* - If "claimJwtId" param exists: Fetches claim data from API
* 3. Populates textarea with formatted claim data
*/
async mounted() {
await this.initializeSettings();
await this.loadClaimData();
}
/**
* Initialize settings from active account
*/
private async initializeSettings() {
const settings = await retrieveSettingsForActiveAccount();
this.activeDid = settings.activeDid || "";
this.apiServer = settings.apiServer || "";
}
/**
* Load claim data from query parameters or API
*/
private async loadClaimData() {
// Try loading from direct claim parameter
if (await this.loadClaimFromQueryParam()) return;
// Try loading from claim JWT ID
await this.loadClaimFromJwtId();
}
/**
* Attempt to load claim from query parameter
* @returns true if claim was loaded successfully
*/
private async loadClaimFromQueryParam(): Promise<boolean> {
this.claimStr = (this.$route.query["claim"] as string) || "";
if (!this.claimStr) return false;
try {
const veriClaim = JSON.parse(this.claimStr);
this.claimStr = JSON.stringify(veriClaim, null, 2);
return true;
} catch (e) {
// ignore parse error
return false;
}
}
/**
* Load claim data from JWT ID via API
*/
private async loadClaimFromJwtId() {
const claimJwtId = (this.$route.query["claimJwtId"] as string) || "";
if (!claimJwtId) return;
const urlPath = libsUtil.isGlobalUri(claimJwtId)
? "/api/claim/byHandle/"
: "/api/claim/";
const url = this.apiServer + urlPath + encodeURIComponent(claimJwtId);
try {
const response = await this.fetchClaimData(url);
this.formatClaimResponse(response, claimJwtId);
} catch (error: unknown) {
this.handleClaimError(error);
}
}
/**
* Fetch claim data from API
*/
private async fetchClaimData(url: string) {
const headers = await serverUtil.getHeaders(this.activeDid);
return await this.axios.get(url, { headers });
}
/**
* Format successful claim response data
*/
private formatClaimResponse(response: unknown, claimJwtId: string) {
if (response.status === 200) {
const claim = response.data?.claim;
claim.lastClaimId = serverUtil.stripEndorserPrefix(claimJwtId);
this.claimStr = JSON.stringify(claim, null, 2);
} else {
throw {
message: "Got an error loading that claim.",
response: {
status: response.status,
statusText: response.statusText,
},
};
}
}
/**
* Handle error loading claim data
*/
private handleClaimError(error: unknown) {
logConsoleAndDb(
"Error retrieving claim: " + errorStringForLog(error),
true,
);
this.$notify(
{
group: "alert",
type: "danger",
title: "Error",
text: "Got an error retrieving claim data.",
},
3000,
);
}
/**
* Submits the edited claim data
* Workflow:
* 1. Parses JSON from textarea
* 2. Sends to server via createAndSubmitClaim
* 3. Shows success/error notification
* @throws Will show error notification if submission fails
*/
async submitClaim() {
const fullClaim = JSON.parse(this.claimStr);
const result = await serverUtil.createAndSubmitClaim(
fullClaim,
this.activeDid,
this.apiServer,
this.axios,
);
if (result.type === "success") {
this.$notify(
{
group: "alert",
type: "success",
title: "Success",
text: "Claim submitted.",
},
5000,
);
} else {
logger.error("Got error submitting the claim:", result);
this.$notify(
{
group: "alert",
type: "danger",
title: "Error",
text: "There was a problem submitting the claim.",
},
5000,
);
}
}
}
</script>