refactor: Replace console logging with logger utility

- Add logger import across multiple view components
- Replace console.error/warn/log with logger methods
- Update error handling to use structured logging
- Improve type safety for error objects
- Add crypto-browserify polyfill for browser environment

The changes improve logging by:
1. Using consistent logging interface
2. Adding structured error logging
3. Improving error type safety
4. Centralizing logging configuration
5. Fixing browser compatibility issues

Affected files:
- Multiple view components
- vite.config.ts
- Build configuration
This commit is contained in:
Matthew Raymer
2025-03-11 09:35:55 +00:00
parent 8cae601148
commit e0aded04b4
1911 changed files with 88846 additions and 401 deletions

View File

@@ -143,7 +143,8 @@
<!--
This "group" of "modal" is the prompt for an answer.
Set "type" as follows: "confirm" for yes/no, and "notification" ones: "-permission", "-mute", "-off"
Set "type" as follows: "confirm" for yes/no, and "notification" ones:
"-permission", "-mute", "-off"
-->
<NotificationGroup group="modal">
<div class="fixed z-[100] top-0 inset-x-0 w-full">
@@ -331,6 +332,7 @@
import { Vue, Component } from "vue-facing-decorator";
import { logConsoleAndDb, retrieveSettingsForActiveAccount } from "./db/index";
import { NotificationIface } from "./constants/app";
import { logger } from "./utils/logger";
interface Settings {
notifyingNewActivityTime?: string;
@@ -344,38 +346,38 @@ export default class App extends Vue {
stopAsking = false;
// created() {
// console.log(
// logger.log(
// "Component created: Reactivity set up.",
// window.location.pathname,
// );
// }
// beforeCreate() {
// console.log("Component beforeCreate: Instance initialized.");
// logger.log("Component beforeCreate: Instance initialized.");
// }
// beforeMount() {
// console.log("Component beforeMount: Template is about to be rendered.");
// logger.log("Component beforeMount: Template is about to be rendered.");
// }
// mounted() {
// console.log("Component mounted: Template is now rendered.");
// logger.log("Component mounted: Template is now rendered.");
// }
// beforeUpdate() {
// console.log("Component beforeUpdate: DOM is about to be updated.");
// logger.log("Component beforeUpdate: DOM is about to be updated.");
// }
// updated() {
// console.log("Component updated: DOM has been updated.");
// logger.log("Component updated: DOM has been updated.");
// }
// beforeUnmount() {
// console.log("Component beforeUnmount: Cleaning up before removal.");
// logger.log("Component beforeUnmount: Cleaning up before removal.");
// }
// unmounted() {
// console.log("Component unmounted: Component removed from the DOM.");
// logger.log("Component unmounted: Component removed from the DOM.");
// }
truncateLongWords(sentence: string) {
@@ -388,42 +390,42 @@ export default class App extends Vue {
async turnOffNotifications(
notification: NotificationIface,
): Promise<boolean> {
console.log("Starting turnOffNotifications...");
logger.log("Starting turnOffNotifications...");
let subscription: PushSubscriptionJSON | null = null;
let allGoingOff = false;
try {
console.log("Retrieving settings for the active account...");
logger.log("Retrieving settings for the active account...");
const settings: Settings = await retrieveSettingsForActiveAccount();
console.log("Retrieved settings:", settings);
logger.log("Retrieved settings:", settings);
const notifyingNewActivity = !!settings?.notifyingNewActivityTime;
const notifyingReminder = !!settings?.notifyingReminderTime;
if (!notifyingNewActivity || !notifyingReminder) {
allGoingOff = true;
console.log("Both notifications are being turned off.");
logger.log("Both notifications are being turned off.");
}
console.log("Checking service worker readiness...");
logger.log("Checking service worker readiness...");
await navigator.serviceWorker?.ready
.then((registration) => {
console.log("Service worker is ready. Fetching subscription...");
logger.log("Service worker is ready. Fetching subscription...");
return registration.pushManager.getSubscription();
})
.then(async (subscript: PushSubscription | null) => {
if (subscript) {
subscription = subscript.toJSON();
console.log("PushSubscription retrieved:", subscription);
logger.log("PushSubscription retrieved:", subscription);
if (allGoingOff) {
console.log("Unsubscribing from push notifications...");
logger.log("Unsubscribing from push notifications...");
await subscript.unsubscribe();
console.log("Successfully unsubscribed.");
logger.log("Successfully unsubscribed.");
}
} else {
logConsoleAndDb("Subscription object is not available.");
console.log("No subscription found.");
logger.log("No subscription found.");
}
})
.catch((error) => {
@@ -432,11 +434,11 @@ export default class App extends Vue {
JSON.stringify(error),
true,
);
console.error("Error during subscription fetch:", error);
logger.error("Error during subscription fetch:", error);
});
if (!subscription) {
console.log("No subscription available. Notifying user...");
logger.log("No subscription available. Notifying user...");
this.$notify(
{
group: "alert",
@@ -446,7 +448,7 @@ export default class App extends Vue {
},
5000,
);
console.log("Exiting as there is no subscription to process.");
logger.log("Exiting as there is no subscription to process.");
return true;
}
@@ -455,12 +457,12 @@ export default class App extends Vue {
};
if (!allGoingOff) {
serverSubscription["notifyType"] = notification.title;
console.log(
logger.log(
`Server subscription updated with notifyType: ${notification.title}`,
);
}
console.log("Sending unsubscribe request to the server...");
logger.log("Sending unsubscribe request to the server...");
const pushServerSuccess = await fetch("/web-push/unsubscribe", {
method: "POST",
headers: {
@@ -475,9 +477,9 @@ export default class App extends Vue {
`Push server failed: ${response.status} ${errorBody}`,
true,
);
console.error("Push server error response:", errorBody);
logger.error("Push server error response:", errorBody);
}
console.log(`Server response status: ${response.status}`);
logger.log(`Server response status: ${response.status}`);
return response.ok;
})
.catch((error) => {
@@ -485,14 +487,14 @@ export default class App extends Vue {
"Push server communication failed: " + JSON.stringify(error),
true,
);
console.error("Error during server communication:", error);
logger.error("Error during server communication:", error);
return false;
});
const message = pushServerSuccess
? "Notification is off."
: "Notification is still on. Try to turn it off again.";
console.log("Server response processed. Message:", message);
logger.log("Server response processed. Message:", message);
this.$notify(
{
@@ -505,11 +507,11 @@ export default class App extends Vue {
);
if (notification.callback) {
console.log("Executing notification callback...");
logger.log("Executing notification callback...");
notification.callback(pushServerSuccess);
}
console.log(
logger.log(
"Completed turnOffNotifications with success:",
pushServerSuccess,
);
@@ -519,7 +521,7 @@ export default class App extends Vue {
"Error turning off notifications: " + JSON.stringify(error),
true,
);
console.error("Critical error in turnOffNotifications:", error);
logger.error("Critical error in turnOffNotifications:", error);
this.$notify(
{

View File

@@ -1,4 +1,5 @@
<template>
<!-- eslint-disable-next-line vue/no-v-html -->
<div class="w-fit" v-html="generateIcon()"></div>
</template>
<script lang="ts">

View File

@@ -162,7 +162,7 @@ export default class GiftedDialog extends Vue {
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (err: any) {
console.error("Error retrieving settings from database:", err);
logger.error("Error retrieving settings from database:", err);
this.$notify(
{
group: "alert",
@@ -311,7 +311,7 @@ export default class GiftedDialog extends Vue {
this.isGiveCreationError(result.response)
) {
const errorMessage = this.getGiveCreationErrorMessage(result);
console.error("Error with give creation result:", result);
logger.error("Error with give creation result:", result);
this.$notify(
{
group: "alert",
@@ -337,7 +337,7 @@ export default class GiftedDialog extends Vue {
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (error: any) {
console.error("Error with give recordation caught:", error);
logger.error("Error with give recordation caught:", error);
const errorMessage =
error.userMessage ||
serverMessageForUser(error) ||

View File

@@ -74,7 +74,7 @@ export default class ImageViewer extends Vue {
}
}
} catch (error) {
console.warn("Share failed, opening in new tab:", error);
logger.warn("Share failed, opening in new tab:", error);
window.open(this.imageUrl, "_blank");
}
}

View File

@@ -61,7 +61,10 @@
</div>
<div class="flex justify-center">
<!-- always have at least one refresh button even without members in case the organizer changes the password -->
<!--
always have at least one refresh button even without members in case the organizer
changes the password
-->
<button
class="w-8 h-8 flex items-center justify-center rounded-full bg-blue-100 text-blue-600 hover:bg-blue-200 hover:text-blue-800 transition-colors"
title="Refresh members list"

View File

@@ -89,6 +89,7 @@ import {
} from "../libs/endorserServer";
import * as libsUtil from "../libs/util";
import { retrieveSettingsForActiveAccount } from "../db/index";
import { logger } from "../utils/logger";
@Component
export default class OfferDialog extends Vue {
@@ -121,7 +122,7 @@ export default class OfferDialog extends Vue {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (err: any) {
console.error("Error retrieving settings from database:", err);
logger.error("Error retrieving settings from database:", err);
this.$notify(
{
group: "alert",
@@ -249,7 +250,7 @@ export default class OfferDialog extends Vue {
this.isOfferCreationError(result.response)
) {
const errorMessage = this.getOfferCreationErrorMessage(result);
console.error("Error with offer creation result:", result);
logger.error("Error with offer creation result:", result);
this.$notify(
{
group: "alert",
@@ -272,7 +273,7 @@ export default class OfferDialog extends Vue {
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (error: any) {
console.error("Error with offer recordation caught:", error);
logger.error("Error with offer recordation caught:", error);
const message =
error.userMessage ||
error.response?.data?.error?.message ||

View File

@@ -129,6 +129,7 @@ import VuePictureCropper, { cropper } from "vue-picture-cropper";
import { DEFAULT_IMAGE_API_SERVER, NotificationIface } from "../constants/app";
import { retrieveSettingsForActiveAccount } from "../db/index";
import { accessToken } from "../libs/crypto";
import { logger } from "../utils/logger";
@Component({ components: { Camera, VuePictureCropper } })
export default class PhotoDialog extends Vue {
@@ -155,7 +156,7 @@ export default class PhotoDialog extends Vue {
this.activeDid = settings.activeDid || "";
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (err: any) {
console.error("Error retrieving settings from database:", err);
logger.error("Error retrieving settings from database:", err);
this.$notify(
{
group: "alert",
@@ -373,7 +374,7 @@ export default class PhotoDialog extends Vue {
window.location.hostname === "localhost" &&
!DEFAULT_IMAGE_API_SERVER.includes("localhost")
) {
console.log(
logger.log(
"Using shared image API server, so only users on that server can play with images.",
);
}
@@ -387,7 +388,7 @@ export default class PhotoDialog extends Vue {
this.close();
this.setImageCallback(response.data.url as string);
} catch (error) {
console.error("Error uploading the image", error);
logger.error("Error uploading the image", error);
this.$notify(
{
group: "alert",

View File

@@ -1,3 +1,4 @@
<!-- eslint-disable vue/no-v-html -->
<template>
<a
v-if="linkToFull && imageUrl"

View File

@@ -111,6 +111,7 @@ import {
import { MASTER_SECRET_KEY } from "../db/tables/secret";
import { urlBase64ToUint8Array } from "../libs/crypto/vc/util";
import * as libsUtil from "../libs/util";
import { logger } from "../utils/logger";
// Example interface for error
interface ErrorResponse {
@@ -495,13 +496,13 @@ export default class PushNotificationPermission extends Vue {
return new Promise<void>((resolve, reject) => {
if (!("serviceWorker" in navigator && "PushManager" in window)) {
const errorMsg = "Push messaging is not supported";
console.warn(errorMsg);
logger.warn(errorMsg);
return reject(new Error(errorMsg));
}
if (window.Notification.permission !== "granted") {
const errorMsg = "Notification permission not granted";
console.warn(errorMsg);
logger.warn(errorMsg);
return reject(new Error(errorMsg));
}
@@ -562,7 +563,7 @@ export default class PushNotificationPermission extends Vue {
body: JSON.stringify(subscription),
}).then((response) => {
if (!response.ok) {
console.error("Bad response subscribing to web push: ", response);
logger.error("Bad response subscribing to web push: ", response);
throw new Error("Failed to send push subscription to server");
}
logConsoleAndDb("Push subscription sent to server successfully.");

View File

@@ -94,7 +94,8 @@
We used to say "account", so we'll keep that in the code,
but it isn't accurate because we don't hold anything for them.
We'll say "profile" to the users.
(Or: settings, face, registry, cache, repo, vault... or separate preferences from identity.)
(Or: settings, face, registry, cache, repo, vault... or separate
preferences from identity.)
-->
<span class="text-xs mt-1">profile</span>
</div>

View File

@@ -5,6 +5,7 @@ import * as SkeletonUtils from "three/addons/utils/SkeletonUtils";
import * as TWEEN from "@tweenjs/tween.js";
import { retrieveSettingsForActiveAccount } from "../../../../db";
import { getHeaders } from "../../../../libs/endorserServer";
import { logger } from "../../../../utils/logger";
const ANIMATION_DURATION_SECS = 10;
const ENDORSER_ENTITY_PREFIX = "https://endorser.ch/entity/";
@@ -82,7 +83,7 @@ export async function loadLandmarks(vue, world, scene, loop) {
},
undefined,
function (error) {
console.error(error);
logger.error(error);
},
);
@@ -117,7 +118,7 @@ export async function loadLandmarks(vue, world, scene, loop) {
world.lights = [...world.lights, light];
}
} else {
console.error(
logger.error(
"Got bad server response status & data of",
resp.status,
resp.data,
@@ -128,7 +129,7 @@ export async function loadLandmarks(vue, world, scene, loop) {
);
}
} catch (error) {
console.error("Got exception contacting server:", error);
logger.error("Got exception contacting server:", error);
vue.setAlert(
"Error With Server",
"There was a problem retrieving your claims from the server.",

View File

@@ -13,6 +13,7 @@ import {
} from "./tables/settings";
import { Temp, TempSchema } from "./tables/temp";
import { DEFAULT_ENDORSER_API_SERVER } from "../constants/app";
import { logger } from "../utils/logger";
// Define types for tables that hold sensitive and non-sensitive data
type SecretTable = { secret: Table<Secret> };
@@ -219,9 +220,9 @@ export async function logConsoleAndDb(
isError = false,
): Promise<void> {
if (isError) {
console.error(`${new Date().toISOString()} ${message}`);
logger.error(`${new Date().toISOString()} ${message}`);
} else {
console.log(`${new Date().toISOString()} ${message}`);
logger.log(`${new Date().toISOString()} ${message}`);
}
await db.open();

View File

@@ -1,6 +1,7 @@
const { app, BrowserWindow } = require("electron");
const path = require("path");
const fs = require("fs");
const logger = require("../utils/logger");
// Check if running in dev mode
const isDev = process.argv.includes("--inspect");
@@ -8,8 +9,8 @@ const isDev = process.argv.includes("--inspect");
function createWindow() {
// Add before createWindow function
const preloadPath = path.join(__dirname, "preload.js");
console.log("Checking preload path:", preloadPath);
console.log("Preload exists:", fs.existsSync(preloadPath));
logger.log("Checking preload path:", preloadPath);
logger.log("Preload exists:", fs.existsSync(preloadPath));
// Create the browser window.
const mainWindow = new BrowserWindow({
@@ -65,25 +66,25 @@ function createWindow() {
if (isDev) {
// Debug info
console.log("Debug Info:");
console.log("Running in dev mode:", isDev);
console.log("App is packaged:", app.isPackaged);
console.log("Process resource path:", process.resourcesPath);
console.log("App path:", app.getAppPath());
console.log("__dirname:", __dirname);
console.log("process.cwd():", process.cwd());
logger.log("Debug Info:");
logger.log("Running in dev mode:", isDev);
logger.log("App is packaged:", app.isPackaged);
logger.log("Process resource path:", process.resourcesPath);
logger.log("App path:", app.getAppPath());
logger.log("__dirname:", __dirname);
logger.log("process.cwd():", process.cwd());
}
const indexPath = path.join(__dirname, "www", "index.html");
if (isDev) {
console.log("Loading index from:", indexPath);
console.log("www path:", path.join(__dirname, "www"));
console.log("www assets path:", path.join(__dirname, "www", "assets"));
logger.log("Loading index from:", indexPath);
logger.log("www path:", path.join(__dirname, "www"));
logger.log("www assets path:", path.join(__dirname, "www", "assets"));
}
if (!fs.existsSync(indexPath)) {
console.error(`Index file not found at: ${indexPath}`);
logger.error(`Index file not found at: ${indexPath}`);
throw new Error("Index file not found");
}
@@ -110,38 +111,38 @@ function createWindow() {
mainWindow
.loadFile(indexPath)
.then(() => {
console.log("Successfully loaded index.html");
logger.log("Successfully loaded index.html");
if (isDev) {
mainWindow.webContents.openDevTools();
console.log("DevTools opened - running in dev mode");
logger.log("DevTools opened - running in dev mode");
}
})
.catch((err) => {
console.error("Failed to load index.html:", err);
console.error("Attempted path:", indexPath);
logger.error("Failed to load index.html:", err);
logger.error("Attempted path:", indexPath);
});
// Listen for console messages from the renderer
mainWindow.webContents.on("console-message", (_event, level, message) => {
console.log("Renderer Console:", message);
logger.log("Renderer Console:", message);
});
// Add right after creating the BrowserWindow
mainWindow.webContents.on(
"did-fail-load",
(event, errorCode, errorDescription) => {
console.error("Page failed to load:", errorCode, errorDescription);
logger.error("Page failed to load:", errorCode, errorDescription);
},
);
mainWindow.webContents.on("preload-error", (event, preloadPath, error) => {
console.error("Preload script error:", preloadPath, error);
logger.error("Preload script error:", preloadPath, error);
});
mainWindow.webContents.on(
"console-message",
(event, level, message, line, sourceId) => {
console.log("Renderer Console:", line, sourceId, message);
logger.log("Renderer Console:", line, sourceId, message);
},
);
@@ -169,5 +170,5 @@ app.on("activate", () => {
// Handle any errors
process.on("uncaughtException", (error) => {
console.error("Uncaught Exception:", error);
logger.error("Uncaught Exception:", error);
});

View File

@@ -1,5 +1,27 @@
const { contextBridge, ipcRenderer } = require("electron");
const logger = {
log: (message, ...args) => {
if (process.env.NODE_ENV !== "production") {
/* eslint-disable no-console */
console.log(message, ...args);
/* eslint-enable no-console */
}
},
warn: (message, ...args) => {
if (process.env.NODE_ENV !== "production") {
/* eslint-disable no-console */
console.warn(message, ...args);
/* eslint-enable no-console */
}
},
error: (message, ...args) => {
/* eslint-disable no-console */
console.error(message, ...args); // Errors should always be logged
/* eslint-enable no-console */
},
};
// Use a more direct path resolution approach
const getPath = (pathType) => {
switch (pathType) {
@@ -19,7 +41,7 @@ const getPath = (pathType) => {
}
};
console.log("Preload script starting...");
logger.log("Preload script starting...");
try {
contextBridge.exposeInMainWorld("electronAPI", {
@@ -50,7 +72,7 @@ try {
},
});
console.log("Preload script completed successfully");
logger.log("Preload script completed successfully");
} catch (error) {
console.error("Error in preload script:", error);
logger.error("Error in preload script:", error);
}

View File

@@ -11,6 +11,7 @@ import {
CONTACT_IMPORT_ONE_URL_PATH_TIME_SAFARI,
} from "../../libs/endorserServer";
import { DEFAULT_DID_PROVIDER_NAME } from "../veramo/setup";
import { logger } from "../../utils/logger";
export const DEFAULT_ROOT_DERIVATION_PATH = "m/84737769'/0'/0'/0'";
@@ -269,35 +270,35 @@ export async function testEncryptionDecryption() {
const testMessage = "Hello, this is a test message! 🚀";
const testPassword = "myTestPassword123";
console.log("Original message:", testMessage);
logger.log("Original message:", testMessage);
// Test encryption
console.log("Encrypting...");
logger.log("Encrypting...");
const encrypted = await encryptMessage(testMessage, testPassword);
console.log("Encrypted result:", encrypted);
logger.log("Encrypted result:", encrypted);
// Test decryption
console.log("Decrypting...");
logger.log("Decrypting...");
const decrypted = await decryptMessage(encrypted, testPassword);
console.log("Decrypted result:", decrypted);
logger.log("Decrypted result:", decrypted);
// Verify
const success = testMessage === decrypted;
console.log("Test " + (success ? "PASSED ✅" : "FAILED ❌"));
console.log("Messages match:", success);
logger.log("Test " + (success ? "PASSED ✅" : "FAILED ❌"));
logger.log("Messages match:", success);
// Test with wrong password
console.log("\nTesting with wrong password...");
logger.log("\nTesting with wrong password...");
try {
await decryptMessage(encrypted, "wrongPassword");
console.log("Should not reach here");
logger.log("Should not reach here");
} catch (error) {
console.log("Correctly failed with wrong password ✅");
logger.log("Correctly failed with wrong password ✅");
}
return success;
} catch (error) {
console.error("Test failed with error:", error);
logger.error("Test failed with error:", error);
return false;
}
}

View File

@@ -27,6 +27,7 @@ import {
peerDidToPublicKeyBytes,
verifyPeerSignature,
} from "../../../libs/crypto/vc/didPeer";
import { logger } from "../../../utils/logger";
export interface JWK {
kty: string;
@@ -69,7 +70,7 @@ export async function registerCredential(passkeyName?: string) {
const credIdBase64Url = verification.registrationInfo?.credentialID as string;
if (attResp.rawId !== credIdBase64Url) {
console.log("Warning! The raw ID does not match the credential ID.");
logger.warn("Warning! The raw ID does not match the credential ID.");
}
const credIdHex = Buffer.from(
base64URLStringToArrayBuffer(credIdBase64Url),

View File

@@ -48,6 +48,7 @@ import {
UserInfo,
CreateAndSubmitClaimResult,
} from "../interfaces";
import { logger } from "../utils/logger";
/**
* Standard context for schema.org data
@@ -174,8 +175,8 @@ export function isEmptyOrHiddenDid(did?: string): boolean {
* testRecursivelyOnStrings(isHiddenDid, obj); // Returns: true
*/
function testRecursivelyOnStrings(
func: (arg0: any) => boolean,
input: any,
func: (arg0: unknown) => boolean,
input: unknown,
): boolean {
// Test direct string values
if (Object.prototype.toString.call(input) === "[object String]") {
@@ -507,7 +508,7 @@ export async function getPlanFromCache(
cred = resp.data.data[0];
planCache.set(handleId, cred);
} else {
console.info(
logger.log(
"[EndorserServer] Plan cache is empty for handle",
handleId,
" Got data:",
@@ -515,7 +516,7 @@ export async function getPlanFromCache(
);
}
} catch (error) {
console.error(
logger.error(
"[EndorserServer] Failed to load plan with handle",
handleId,
" Got error:",
@@ -543,7 +544,7 @@ export async function setPlanInCache(
* @param {any} error - Error thrown from Endorser server call
* @returns {string|undefined} User-friendly message or undefined if none found
*/
export function serverMessageForUser(error: any): string | undefined {
export function serverMessageForUser(error: unknown): string | undefined {
return error?.response?.data?.error?.message;
}
@@ -554,7 +555,7 @@ export function serverMessageForUser(error: any): string | undefined {
* @param error
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function errorStringForLog(error: any) {
export function errorStringForLog(error: unknown) {
let stringifiedError = "" + error;
try {
stringifiedError = JSON.stringify(error);
@@ -984,7 +985,7 @@ export async function createAndSubmitClaim(
return { type: "success", response };
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (error: any) {
console.error("Error submitting claim:", error);
logger.error("Error submitting claim:", error);
const errorMessage: string =
serverMessageForUser(error) ||
error.message ||
@@ -1330,7 +1331,7 @@ export async function register(
}
return { error: message };
} else {
console.error(resp);
logger.error(resp);
return { error: "Got a server error when registering." };
}
}
@@ -1360,7 +1361,7 @@ export async function setVisibilityUtil(
}
return { success };
} else {
console.error(
logger.error(
"Got some bad server response when setting visibility: ",
resp.status,
resp,
@@ -1370,7 +1371,7 @@ export async function setVisibilityUtil(
return { error: message };
}
} catch (err) {
console.error("Got some error when setting visibility:", err);
logger.error("Got some error when setting visibility:", err);
return { error: "Check connectivity and try again." };
}
}

View File

@@ -27,6 +27,7 @@ import {
import { KeyMeta } from "../libs/crypto/vc";
import { createPeerDid } from "../libs/crypto/vc/didPeer";
import { registerCredential } from "../libs/crypto/vc/passkeyDidPeer";
import { logger } from "../utils/logger";
export interface GiverReceiverInputInfo {
did?: string;
@@ -222,7 +223,7 @@ export async function retrieveConfirmerIdList(
};
return result;
} else {
console.error(
logger.error(
"Bad response status of",
response.status,
"for confirmers:",
@@ -610,7 +611,7 @@ export const sendTestThroughPushServer = async (
message: `Test, where you will see this message ${ skipFilter ? "un" : "" }filtered.`,
title: skipFilter ? DIRECT_PUSH_TITLE : "Your Web Push",
};
console.log("Sending a test web push message:", newPayload);
logger.log("Sending a test web push message:", newPayload);
const payloadStr = JSON.stringify(newPayload);
const response = await axios.post(
pushUrl + "/web-push/send-test",
@@ -622,6 +623,6 @@ export const sendTestThroughPushServer = async (
},
);
console.log("Got response from web push server:", response);
logger.log("Got response from web push server:", response);
return response;
};

View File

@@ -35,9 +35,10 @@ import { handleApiError } from "./services/api";
import { AxiosError } from "axios";
import { DeepLinkHandler } from "./services/deepLinks";
import { logConsoleAndDb } from "./db";
import { logger } from "./utils/logger";
console.log("[Capacitor] Starting initialization");
console.log("[Capacitor] Platform:", process.env.VITE_PLATFORM);
logger.log("[Capacitor] Starting initialization");
logger.log("[Capacitor] Platform:", process.env.VITE_PLATFORM);
const app = initializeApp();
@@ -84,6 +85,6 @@ const handleDeepLink = async (data: { url: string }) => {
// Register deep link handler with Capacitor
App.addListener("appUrlOpen", handleDeepLink);
console.log("[Capacitor] Mounting app");
logger.log("[Capacitor] Mounting app");
app.mount("#app");
console.log("[Capacitor] App mounted");
logger.log("[Capacitor] App mounted");

View File

@@ -8,16 +8,17 @@ import Notifications from "notiwind";
import "./assets/styles/tailwind.css";
import { FontAwesomeIcon } from "./lib/fontawesome";
import Camera from "simple-vue-camera";
import { logger } from "./utils/logger";
// Global Error Handler
function setupGlobalErrorHandler(app: VueApp) {
console.log("[App Init] Setting up global error handler");
logger.log("[App Init] Setting up global error handler");
app.config.errorHandler = (
err: unknown,
instance: ComponentPublicInstance | null,
info: string,
) => {
console.error("[App Error] Global Error Handler:", {
logger.error("[App Error] Global Error Handler:", {
error: err,
info,
component: instance?.$options.name || "unknown",
@@ -31,30 +32,30 @@ function setupGlobalErrorHandler(app: VueApp) {
// Function to initialize the app
export function initializeApp() {
console.log("[App Init] Starting app initialization");
console.log("[App Init] Platform:", process.env.VITE_PLATFORM);
logger.log("[App Init] Starting app initialization");
logger.log("[App Init] Platform:", process.env.VITE_PLATFORM);
const app = createApp(App);
console.log("[App Init] Vue app created");
logger.log("[App Init] Vue app created");
app.component("FontAwesome", FontAwesomeIcon).component("camera", Camera);
console.log("[App Init] Components registered");
logger.log("[App Init] Components registered");
const pinia = createPinia();
app.use(pinia);
console.log("[App Init] Pinia store initialized");
logger.log("[App Init] Pinia store initialized");
app.use(VueAxios, axios);
console.log("[App Init] Axios initialized");
logger.log("[App Init] Axios initialized");
app.use(router);
console.log("[App Init] Router initialized");
logger.log("[App Init] Router initialized");
app.use(Notifications);
console.log("[App Init] Notifications initialized");
logger.log("[App Init] Notifications initialized");
setupGlobalErrorHandler(app);
console.log("[App Init] App initialization complete");
logger.log("[App Init] App initialization complete");
return app;
}

View File

@@ -9,6 +9,7 @@ import Notifications from "notiwind";
import "./assets/styles/tailwind.css";
import { FontAwesomeIcon } from "./lib/fontawesome";
import Camera from "simple-vue-camera";
import { logger } from "./utils/logger";
// Can trigger this with a 'throw' inside some top-level function, eg. on the HomeView
function setupGlobalErrorHandler(app: VueApp) {
@@ -18,7 +19,7 @@ function setupGlobalErrorHandler(app: VueApp) {
instance: ComponentPublicInstance | null,
info: string,
) => {
console.error(
logger.error(
"Ouch! Global Error Handler.",
"Error:",
err,

View File

@@ -7,6 +7,7 @@ import {
RouteRecordRaw,
} from "vue-router";
import { accountsDBPromise } from "../db/index";
import { logger } from "../utils/logger";
/**
*
@@ -307,7 +308,7 @@ const errorHandler = (
from: RouteLocationNormalized,
) => {
// Handle the error here
console.error("Caught in top level error handler:", error, to, from);
logger.error("Caught in top level error handler:", error, to, from);
alert("Something is very wrong. Try reloading or restarting the app.");
// You can also perform additional actions, such as displaying an error message or redirecting the user to a specific page

View File

@@ -1,8 +1,8 @@
import { AxiosError } from "axios";
import { logger } from "../utils/logger";
export const handleApiError = (error: AxiosError, endpoint: string) => {
if (process.env.VITE_PLATFORM === "capacitor") {
console.error(`[Capacitor API Error] ${endpoint}:`, {
logger.error(`[Capacitor API Error] ${endpoint}:`, {
message: error.message,
status: error.response?.status,
data: error.response?.data,
@@ -16,7 +16,7 @@ export const handleApiError = (error: AxiosError, endpoint: string) => {
// Specific handling for rate limits
if (error.response?.status === 400) {
console.warn(`[Rate Limit] ${endpoint}`);
logger.warn(`[Rate Limit] ${endpoint}`);
return null;
}

View File

@@ -1,4 +1,5 @@
import axios from "axios";
import { logger } from "../utils/logger";
interface PlanResponse {
data?: unknown;
@@ -11,14 +12,14 @@ export const loadPlanWithRetry = async (
retries = 3,
): Promise<PlanResponse> => {
try {
console.log(`[Plan Service] Loading plan ${handle}, attempt 1/${retries}`);
console.log(
logger.log(`[Plan Service] Loading plan ${handle}, attempt 1/${retries}`);
logger.log(
`[Plan Service] Context: Deep link handle=${handle}, isClaimFlow=${handle.includes("claim")}`,
);
// Different endpoint if this is a claim flow
const response = await loadPlan(handle);
console.log(`[Plan Service] Plan ${handle} loaded successfully:`, {
logger.log(`[Plan Service] Plan ${handle} loaded successfully:`, {
status: response?.status,
headers: response?.headers,
data: response?.data,
@@ -26,7 +27,7 @@ export const loadPlanWithRetry = async (
return response;
} catch (error: unknown) {
console.error(`[Plan Service] Error loading plan ${handle}:`, {
logger.error(`[Plan Service] Error loading plan ${handle}:`, {
message: (error as Error).message,
status: (error as { response?: { status?: number } })?.response?.status,
statusText: (error as { response?: { statusText?: string } })?.response
@@ -43,7 +44,7 @@ export const loadPlanWithRetry = async (
});
if (retries > 1) {
console.log(
logger.log(
`[Plan Service] Retrying plan ${handle}, ${retries - 1} attempts remaining`,
);
await new Promise((resolve) => setTimeout(resolve, 1000));
@@ -58,19 +59,19 @@ export const loadPlanWithRetry = async (
};
export const loadPlan = async (handle: string): Promise<PlanResponse> => {
console.log(`[Plan Service] Making API request for plan ${handle}`);
logger.log(`[Plan Service] Making API request for plan ${handle}`);
const endpoint = handle.includes("claim")
? `/api/claims/${handle}`
: `/api/plans/${handle}`;
console.log(`[Plan Service] Using endpoint: ${endpoint}`);
logger.log(`[Plan Service] Using endpoint: ${endpoint}`);
try {
const response = await axios.get(endpoint);
return response;
} catch (error: unknown) {
console.error(`[Plan Service] API request failed for ${handle}:`, {
logger.error(`[Plan Service] API request failed for ${handle}:`, {
endpoint,
error: (error as Error).message,
response: (error as { response?: { data?: unknown } })?.response?.data,

View File

@@ -4,7 +4,7 @@ import { AppString } from "../constants/app";
import { retrieveSettingsForActiveAccount } from "../db";
import { SERVICE_ID } from "../libs/endorserServer";
import { deriveAddress, newIdentifier } from "../libs/crypto";
import { logger } from "../utils/logger";
/**
* Get User #0 to sign & submit a RegisterAction for the user's activeDid.
*/
@@ -58,5 +58,5 @@ export async function testServerRegisterUser() {
};
const resp = await axios.post(url, payload, { headers });
console.log("User registration result:", resp);
logger.log("User registration result:", resp);
}

18
src/utils/logger.ts Normal file
View File

@@ -0,0 +1,18 @@
export const logger = {
log: (message: string, ...args: unknown[]) => {
if (process.env.NODE_ENV !== "production") {
// eslint-disable-next-line no-console
console.log(message, ...args);
}
},
warn: (message: string, ...args: unknown[]) => {
if (process.env.NODE_ENV !== "production") {
// eslint-disable-next-line no-console
console.warn(message, ...args);
}
},
error: (message: string, ...args: unknown[]) => {
// eslint-disable-next-line no-console
console.error(message, ...args); // Errors should always be logged
},
};

View File

@@ -976,6 +976,7 @@ import {
retrieveAccountMetadata,
} from "../libs/util";
import { UserProfile } from "@/libs/partnerServer";
import { logger } from "../utils/logger";
const inputImportFileNameRef = ref<Blob>();
@@ -1109,12 +1110,12 @@ export default class AccountViewView extends Vue {
}
} catch (error) {
// this can happen when running automated tests in dev mode because notifications don't work
console.error(
logger.error(
"Telling user to clear cache at page create because:",
error,
);
// this sometimes gives different information on the error
console.error(
logger.error(
"To repeat with concatenated error: telling user to clear cache at page create because: " +
error,
);
@@ -1521,7 +1522,7 @@ export default class AccountViewView extends Vue {
* @param {Error} error - The error object.
*/
private handleExportError(error: unknown) {
console.error("Export Error:", error);
logger.error("Export Error:", error);
this.$notify(
{
group: "alert",
@@ -1591,7 +1592,7 @@ export default class AccountViewView extends Vue {
query: { contacts: JSON.stringify(contactRows) },
});
} catch (error) {
console.error("Error checking contact imports:", error);
logger.error("Error checking contact imports:", error);
this.$notify(
{
group: "alert",
@@ -1607,7 +1608,7 @@ export default class AccountViewView extends Vue {
}
private progressCallback(progress: ImportProgress) {
console.log(
logger.log(
`Import progress: ${progress.completedRows} of ${progress.totalRows} rows completed.`,
);
if (progress.done) {
@@ -1659,7 +1660,7 @@ export default class AccountViewView extends Vue {
await updateAccountSettings(did, { isRegistered: true });
this.isRegistered = true;
} catch (err) {
console.error("Got an error updating settings:", err);
logger.error("Got an error updating settings:", err);
this.$notify(
{
group: "alert",
@@ -1698,7 +1699,7 @@ export default class AccountViewView extends Vue {
if (error instanceof AxiosError) {
if (error.status == 400 || error.status == 404) {
// no worries: they probably just aren't registered and don't have any limits
console.log(
logger.log(
"Got 400 or 404 response retrieving limits which probably means they're not registered:",
error,
);
@@ -1707,11 +1708,11 @@ export default class AccountViewView extends Vue {
const data = error.response?.data as ErrorResponse;
this.limitsMessage =
(data?.error?.message as string) || "Bad server response.";
console.error("Got bad response retrieving limits:", error);
logger.error("Got bad response retrieving limits:", error);
}
} else {
this.limitsMessage = "Got an error retrieving limits.";
console.error("Got some error retrieving limits:", error);
logger.error("Got some error retrieving limits:", error);
}
}
@@ -1788,7 +1789,7 @@ export default class AccountViewView extends Vue {
window.location.hostname === "localhost" &&
!DEFAULT_IMAGE_API_SERVER.includes("localhost")
) {
console.log(
logger.log(
"Using shared image API server, so only users on that server can play with images.",
);
}
@@ -1802,7 +1803,7 @@ export default class AccountViewView extends Vue {
// don't bother with a notification
// (either they'll simply continue or they're canceling and going back)
} else {
console.error("Non-success deleting image:", response);
logger.error("Non-success deleting image:", response);
this.$notify(
{
group: "alert",
@@ -1822,10 +1823,10 @@ export default class AccountViewView extends Vue {
this.profileImageUrl = undefined;
} catch (error) {
console.error("Error deleting image:", error);
logger.error("Error deleting image:", error);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
if ((error as any).response.status === 404) {
console.error("The image was already deleted:", error);
logger.error("The image was already deleted:", error);
await updateAccountSettings(this.activeDid, {
profileImageUrl: undefined,

View File

@@ -39,6 +39,7 @@ 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
@@ -141,7 +142,7 @@ export default class ClaimAddRawView extends Vue {
/**
* Format successful claim response data
*/
private formatClaimResponse(response: any, claimJwtId: string) {
private formatClaimResponse(response: unknown, claimJwtId: string) {
if (response.status === 200) {
const claim = response.data?.claim;
claim.lastClaimId = serverUtil.stripEndorserPrefix(claimJwtId);
@@ -203,7 +204,7 @@ export default class ClaimAddRawView extends Vue {
5000,
);
} else {
console.error("Got error submitting the claim:", result);
logger.error("Got error submitting the claim:", result);
this.$notify(
{
group: "alert",

View File

@@ -18,6 +18,7 @@ import { APP_SERVER, NotificationIface } from "../constants/app";
import { db, retrieveSettingsForActiveAccount } from "../db/index";
import * as serverUtil from "../libs/endorserServer";
import { GenericCredWrapper, GenericVerifiableCredential } from "../interfaces";
import { logger } from "../utils/logger";
@Component
export default class ClaimCertificateView extends Vue {
$notify!: (notification: NotificationIface, timeout?: number) => void;
@@ -69,7 +70,7 @@ export default class ClaimCertificateView extends Vue {
throw new Error(`Error fetching claim: ${response.statusText}`);
}
} catch (error) {
console.error("Failed to load claim:", error);
logger.error("Failed to load claim:", error);
this.$notify({
group: "alert",
type: "danger",

View File

@@ -14,7 +14,7 @@ import QRCode from "qrcode";
import { APP_SERVER, NotificationIface } from "../constants/app";
import { db, retrieveSettingsForActiveAccount } from "../db/index";
import * as endorserServer from "../libs/endorserServer";
import { logger } from "../utils/logger";
@Component
export default class ClaimReportCertificateView extends Vue {
$notify!: (notification: NotificationIface, timeout?: number) => void;
@@ -53,7 +53,7 @@ export default class ClaimReportCertificateView extends Vue {
throw new Error(`Error fetching claim: ${response.statusText}`);
}
} catch (error) {
console.error("Failed to load claim:", error);
logger.error("Failed to load claim:", error);
this.$notify({
group: "alert",
type: "danger",

View File

@@ -366,7 +366,9 @@
</div>
</div>
<!-- Note that a similar section is found in ConfirmGiftView.vue, and kinda in HiddenDidDialog.vue -->
<!--
Note that a similar section is found in ConfirmGiftView.vue, and kinda in HiddenDidDialog.vue
-->
<h2
class="font-bold uppercase text-xl text-blue-500 mt-8 cursor-pointer"
@click="showVeriClaimDump = !showVeriClaimDump"
@@ -554,6 +556,7 @@ import {
ProviderInfo,
} from "../interfaces";
import * as libsUtil from "../libs/util";
import { logger } from "../utils/logger";
@Component({
components: { GiftedDialog, QuickNav },
@@ -617,7 +620,7 @@ export default class ClaimView extends Vue {
}
async created() {
console.log("ClaimView created");
logger.log("ClaimView created");
const settings = await retrieveSettingsForActiveAccount();
this.activeDid = settings.activeDid || "";
this.apiServer = settings.apiServer || "";
@@ -687,7 +690,7 @@ export default class ClaimView extends Vue {
}
async loadClaim(claimId: string, userDid: string) {
console.log("[ClaimView] loadClaim called with claimId:", claimId);
logger.log("[ClaimView] loadClaim called with claimId:", claimId);
const urlPath = libsUtil.isGlobalUri(claimId)
? "/api/claim/byHandle/"
: "/api/claim/";
@@ -695,7 +698,7 @@ export default class ClaimView extends Vue {
const headers = await serverUtil.getHeaders(userDid);
try {
console.log("[ClaimView] Making API request to:", url);
logger.log("[ClaimView] Making API request to:", url);
const resp = await this.axios.get(url, { headers });
if (resp.status === 200) {
this.veriClaim = resp.data;
@@ -707,7 +710,7 @@ export default class ClaimView extends Vue {
);
} else {
// actually, axios typically throws an error so we never get here
console.error("Error getting claim:", resp);
logger.error("Error getting claim:", resp);
this.$notify(
{
group: "alert",
@@ -735,7 +738,7 @@ export default class ClaimView extends Vue {
if (giveResp.status === 200 && giveResp.data.data?.length > 0) {
this.detailsForGive = giveResp.data.data[0];
} else {
console.error("Error getting detailed give info:", giveResp);
logger.error("Error getting detailed give info:", giveResp);
}
// look for providers
@@ -754,7 +757,7 @@ export default class ClaimView extends Vue {
) {
this.providersForGive = providerResp.data.data;
} else {
console.error("Error getting give providers:", giveResp);
logger.error("Error getting give providers:", giveResp);
this.$notify(
{
group: "alert",
@@ -777,7 +780,7 @@ export default class ClaimView extends Vue {
if (offerResp.status === 200) {
this.detailsForOffer = offerResp.data.data[0];
} else {
console.error("Error getting detailed offer info:", offerResp);
logger.error("Error getting detailed offer info:", offerResp);
this.$notify(
{
group: "alert",
@@ -807,7 +810,7 @@ export default class ClaimView extends Vue {
}
} catch (error: unknown) {
const serverError = error as AxiosError;
console.error("Error retrieving claim:", serverError);
logger.error("Error retrieving claim:", serverError);
this.$notify(
{
group: "alert",
@@ -832,7 +835,7 @@ export default class ClaimView extends Vue {
this.fullClaimDump = yaml.dump(this.fullClaim);
} else {
// actually, axios typically throws an error so we never get here
console.error("Error getting full claim:", resp);
logger.error("Error getting full claim:", resp);
this.$notify(
{
group: "alert",
@@ -844,7 +847,7 @@ export default class ClaimView extends Vue {
);
}
} catch (error: unknown) {
console.error("Error retrieving full claim:", error);
logger.error("Error retrieving full claim:", error);
const serverError = error as AxiosError;
if (serverError.response?.status === 403) {
let issuerPhrase = "";
@@ -939,7 +942,7 @@ export default class ClaimView extends Vue {
5000,
);
} else {
console.error("Got error submitting the confirmation:", result);
logger.error("Got error submitting the confirmation:", result);
this.$notify(
{
group: "alert",
@@ -1029,7 +1032,7 @@ export default class ClaimView extends Vue {
};
(this.$router as Router).push(route);
} else {
console.error(
logger.error(
"Unrecognized claim type for edit:",
this.veriClaim.claimType,
);

View File

@@ -275,7 +275,9 @@
</div>
</div>
<!-- Note that a similar section is found in ClaimView.vue, and kinda in HiddenDidDialog.vue -->
<!--
Note that a similar section is found in ClaimView.vue, and kinda in HiddenDidDialog.vue
-->
<h2
class="font-bold uppercase text-xl text-blue-500 mt-8 cursor-pointer"
@click="showVeriClaimDump = !showVeriClaimDump"
@@ -445,7 +447,7 @@ import { displayAmount } from "../libs/endorserServer";
import * as libsUtil from "../libs/util";
import { retrieveAccountDids } from "../libs/util";
import TopMessage from "../components/TopMessage.vue";
import { logger } from "../utils/logger";
/**
* ConfirmGiftView Component
*
@@ -515,7 +517,7 @@ export default class ConfirmGiftView extends Vue {
await this.initializeSettings();
await this.loadClaimFromUrl();
} catch (error) {
console.error("Error in mounted:", error);
logger.error("Error in mounted:", error);
this.handleMountError(error);
} finally {
this.isLoading = false;
@@ -610,7 +612,7 @@ export default class ConfirmGiftView extends Vue {
throw new Error("Error getting claim: " + resp.status);
}
} catch (error) {
console.error("Error getting claim:", error);
logger.error("Error getting claim:", error);
throw new Error("There was a problem retrieving that claim.");
}
}
@@ -631,7 +633,7 @@ export default class ConfirmGiftView extends Vue {
throw new Error("Error getting detailed give info: " + resp.status);
}
} catch (error) {
console.error("Error getting detailed give info:", error);
logger.error("Error getting detailed give info:", error);
throw new Error("Something went wrong retrieving gift data.");
}
}

View File

@@ -132,7 +132,7 @@ import {
SCHEMA_ORG_CONTEXT,
} from "../libs/endorserServer";
import { retrieveAccountCount } from "../libs/util";
import { logger } from "../utils/logger";
@Component({ components: { QuickNav } })
export default class ContactAmountssView extends Vue {
$notify!: (notification: NotificationIface, timeout?: number) => void;
@@ -165,7 +165,7 @@ export default class ContactAmountssView extends Vue {
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (err: any) {
console.error("Error retrieving settings or gives.", err);
logger.error("Error retrieving settings or gives.", err);
this.$notify(
{
group: "alert",
@@ -194,7 +194,7 @@ export default class ContactAmountssView extends Vue {
if (resp.status === 200) {
result = resp.data.data;
} else {
console.error(
logger.error(
"Got bad response status & data of",
resp.status,
resp.data,
@@ -221,7 +221,7 @@ export default class ContactAmountssView extends Vue {
if (resp2.status === 200) {
result = R.concat(result, resp2.data.data);
} else {
console.error(
logger.error(
"Got bad response status & data of",
resp2.status,
resp2.data,

View File

@@ -80,7 +80,7 @@ import { NotificationIface } from "../constants/app";
import { db, retrieveSettingsForActiveAccount } from "../db/index";
import { Contact } from "../db/tables/contacts";
import { GiverReceiverInputInfo } from "../libs/util";
import { logger } from "../utils/logger";
@Component({
components: { GiftedDialog, QuickNav, EntityIcon },
})
@@ -114,7 +114,7 @@ export default class ContactGiftingView extends Vue {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (err: any) {
console.error("Error retrieving settings & contacts:", err);
logger.error("Error retrieving settings & contacts:", err);
this.$notify(
{
group: "alert",

View File

@@ -109,7 +109,7 @@ import {
import { decodeEndorserJwt, ETHR_DID_PREFIX } from "../libs/crypto/vc";
import { retrieveAccountMetadata } from "../libs/util";
import { Router } from "vue-router";
import { logger } from "../utils/logger";
@Component({
components: {
QrcodeStream,
@@ -210,7 +210,7 @@ export default class ContactQRScanShow extends Vue {
return;
}
} catch (e) {
console.error("Error parsing QR info:", e);
logger.error("Error parsing QR info:", e);
this.danger("Could not parse the QR info.", "Read Error");
return;
}
@@ -274,7 +274,7 @@ export default class ContactQRScanShow extends Vue {
}
}
} catch (e) {
console.error("Error saving contact info:", e);
logger.error("Error saving contact info:", e);
this.$notify(
{
group: "alert",
@@ -310,7 +310,7 @@ export default class ContactQRScanShow extends Vue {
if (result.error) {
this.danger(result.error as string, "Error Setting Visibility");
} else if (!result.success) {
console.error("Got strange result from setting visibility:", result);
logger.error("Got strange result from setting visibility:", result);
}
}
@@ -360,7 +360,7 @@ export default class ContactQRScanShow extends Vue {
);
}
} catch (error) {
console.error("Error when registering:", error);
logger.error("Error when registering:", error);
let userMessage = "There was an error.";
const serverError = error as AxiosError;
if (serverError) {
@@ -389,7 +389,7 @@ export default class ContactQRScanShow extends Vue {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
onScanError(error: any) {
console.error("Scan was invalid:", error);
logger.error("Scan was invalid:", error);
this.$notify(
{
group: "alert",

View File

@@ -392,7 +392,7 @@ import {
} from "../libs/endorserServer";
import * as libsUtil from "../libs/util";
import { generateSaveAndActivateIdentity } from "../libs/util";
import { logger } from "../utils/logger";
@Component({
components: {
GiftedDialog,
@@ -683,7 +683,7 @@ export default class ContactsView extends Vue {
}
}
} else {
console.error(
logger.error(
"Got bad response status & data of",
resp.status,
resp.data,
@@ -1161,7 +1161,7 @@ export default class ContactsView extends Vue {
}
return true;
} else {
console.error(
logger.error(
"Got strange result from setting visibility. It can happen when setting visibility on oneself.",
result,
);

View File

@@ -252,6 +252,7 @@ import {
} from "../libs/endorserServer";
import * as libsUtil from "../libs/util";
import EntityIcon from "../components/EntityIcon.vue";
import { logger } from "../utils/logger";
/**
* DIDView Component
@@ -517,7 +518,7 @@ export default class DIDView extends Vue {
);
}
} catch (error) {
console.error("Error when registering:", error);
logger.error("Error when registering:", error);
let userMessage = "There was an error.";
const serverError = error as AxiosError;
if (serverError) {
@@ -551,7 +552,7 @@ export default class DIDView extends Vue {
*/
public async loadClaimsAbout() {
if (!this.viewingDid) {
console.error("This should never be called without a DID.");
logger.error("This should never be called without a DID.");
return;
}
@@ -573,7 +574,7 @@ export default class DIDView extends Vue {
if (response.status !== 200) {
const details = await response.text();
console.error("Problem with full search:", details);
logger.error("Problem with full search:", details);
this.$notify(
{
group: "alert",
@@ -592,7 +593,7 @@ export default class DIDView extends Vue {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (e: any) {
console.error("Error with feed load:", e);
logger.error("Error with feed load:", e);
this.$notify(
{
group: "alert",
@@ -733,7 +734,7 @@ export default class DIDView extends Vue {
}
return true;
} else {
console.error("Got strange result from setting visibility:", result);
logger.error("Got strange result from setting visibility:", result);
const message =
(result.error as string) || "Could not set visibility on the server.";
this.$notify(
@@ -796,7 +797,7 @@ export default class DIDView extends Vue {
3000,
);
} else {
console.error("Got bad server response checking visibility:", resp);
logger.error("Got bad server response checking visibility:", resp);
const message = resp.data.error?.message || "Got bad server response.";
this.$notify(
{
@@ -809,7 +810,7 @@ export default class DIDView extends Vue {
);
}
} catch (err) {
console.error("Caught error from request to check visibility:", err);
logger.error("Caught error from request to check visibility:", err);
this.$notify(
{
group: "alert",

View File

@@ -191,7 +191,10 @@
<p class="text-lg text-slate-500">
<span v-if="isLocalActive">
<span v-if="searchBox"> None found in the selected area. </span>
<!-- Otherwise there's no search area selected so we'll just leave the search box for them to click. -->
<!--
Otherwise there's no search area selected so we'll just leave the search box for them
to click.
-->
</span>
<span v-else-if="isAnywhereActive"
>No projects were found with that search.</span
@@ -329,7 +332,7 @@ import {
getHeaders,
} from "../libs/endorserServer";
import { OnboardPage, retrieveAccountDids } from "../libs/util";
import { logger } from "../utils/logger";
interface Tile {
indexLat: number;
indexLon: number;
@@ -502,9 +505,9 @@ export default class DiscoverView extends Vue {
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (e: any) {
console.error("Error with search all:", e);
logger.error("Error with search all:", e);
// this sometimes gives different information
console.error("Error with search all (error added): " + e);
logger.error("Error with search all (error added): " + e);
this.$notify(
{
group: "alert",
@@ -596,7 +599,7 @@ export default class DiscoverView extends Vue {
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (e: any) {
console.error("Error with search local:", e);
logger.error("Error with search local:", e);
this.$notify(
{
group: "alert",

View File

@@ -279,6 +279,7 @@ import {
} from "../libs/endorserServer";
import * as libsUtil from "../libs/util";
import { retrieveAccountDids } from "../libs/util";
import { logger } from "../utils/logger";
@Component({
components: {
@@ -549,7 +550,7 @@ export default class GiftedDetails extends Vue {
window.location.hostname === "localhost" &&
!DEFAULT_IMAGE_API_SERVER.includes("localhost")
) {
console.log(
logger.log(
"Using shared image API server, so only users on that server can play with images.",
);
}
@@ -563,7 +564,7 @@ export default class GiftedDetails extends Vue {
// don't bother with a notification
// (either they'll simply continue or they're canceling and going back)
} else {
console.error("Problem deleting image:", response);
logger.error("Problem deleting image:", response);
this.$notify(
{
group: "alert",
@@ -580,10 +581,10 @@ export default class GiftedDetails extends Vue {
localStorage.removeItem("imageUrl");
this.imageUrl = "";
} catch (error) {
console.error("Error deleting image:", error);
logger.error("Error deleting image:", error);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
if ((error as any).response.status === 404) {
console.log("Weird: the image was already deleted.", error);
logger.log("Weird: the image was already deleted.", error);
localStorage.removeItem("imageUrl");
this.imageUrl = "";
@@ -816,7 +817,7 @@ export default class GiftedDetails extends Vue {
this.isGiveCreationError(result.response)
) {
const errorMessage = this.getGiveCreationErrorMessage(result);
console.error("Error with give creation result:", result);
logger.error("Error with give creation result:", result);
this.$notify(
{
group: "alert",
@@ -845,7 +846,7 @@ export default class GiftedDetails extends Vue {
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (error: any) {
console.error("Error with give recordation caught:", error);
logger.error("Error with give recordation caught:", error);
const errorMessage =
error.userMessage ||
error.response?.data?.error?.message ||

View File

@@ -42,16 +42,21 @@
<h2 class="text-xl font-semibold mt-4">New Activity Notifications</h2>
<div>
<p>
The New Activity Notification will be sent to you when there is new, relevant activity for you.
The New Activity Notification will be sent to you when there is new, relevant activity
for you.
It will only trigger if something involves you or a project of interest; it will not
bug you for other, general activity.
</p>
<p>
This type is not as reliable as a Reminder Notification because mobile devices often suppress
such notifications to save battery. (If you want to quickly check for relevant activity daily,
use the Reminder Notification and open the app and look for a large green button that points out new
activity that is personal to you. We are working on other ways to notify you more
reliably -- <router-link class="text-blue-500" to="/help">go here to follow us or contact us</router-link>.)
This type is not as reliable as a Reminder Notification because mobile devices often
suppress such notifications to save battery. (If you want to quickly check for relevant
activity daily, use the Reminder Notification and open the app and look for a large green
button that points out new activity that is personal to you. We are working on other
ways to notify you more reliably.
<router-link class="text-blue-500" to="/help">
go here to follow us or contact us
<font-awesome icon="chevron-right" class="fa-fw"></font-awesome>
</router-link>.)
</p>
</div>
</div>

View File

@@ -314,7 +314,7 @@ import PushNotificationPermission from "../components/PushNotificationPermission
import { db } from "../db/index";
import { MASTER_SETTINGS_KEY } from "../db/tables/settings";
import { Router } from "vue-router";
import { logger } from "../utils/logger";
@Component({ components: { PushNotificationPermission, QuickNav } })
export default class HelpNotificationsView extends Vue {
$notify!: (notification: NotificationIface, timeout?: number) => void;
@@ -327,7 +327,7 @@ export default class HelpNotificationsView extends Vue {
const fullSub = await registration?.pushManager.getSubscription();
this.subscriptionJSON = fullSub?.toJSON();
} catch (error) {
console.error("Mount error:", error);
logger.error("Mount error:", error);
}
}
@@ -369,7 +369,7 @@ export default class HelpNotificationsView extends Vue {
5000,
);
} catch (error) {
console.error("Got an error sending test notification:", error);
logger.error("Got an error sending test notification:", error);
this.$notify(
{
group: "alert",
@@ -402,7 +402,7 @@ export default class HelpNotificationsView extends Vue {
);
})
.catch((error) => {
console.error("Got a notification error:", error);
logger.error("Got a notification error:", error);
this.$notify(
{
group: "alert",

View File

@@ -98,7 +98,8 @@
<p>
Enable notifications from the Account page <font-awesome icon="circle-user" />.
Those notifications might show up on the device depending on your settings.
For the most reliable habits, set an alarm or do some other ritual to record gratitude every day.
For the most reliable habits, set an alarm or do some other ritual to record gratitude
every day.
</p>
</div>

View File

@@ -10,7 +10,10 @@
<OnboardingDialog ref="onboardingDialog" />
<!-- prompt to install notifications with notificationsSupported, which we're making an advanced feature -->
<!--
prompt to install notifications with notificationsSupported, which we're making an advanced
feature
-->
<div class="mb-8 mt-8">
<div
v-if="false"
@@ -76,7 +79,9 @@
<div v-else>
<!-- !isCreatingIdentifier -->
<!-- They should have an identifier, even if it's an auto-generated one that they'll never use. -->
<!--
They should have an identifier, even if it's an auto-generated one that they'll never use.
-->
<div class="mb-4">
<div
v-if="!isRegistered"
@@ -278,39 +283,6 @@
</span>
</span>
<span class="col-span-10 justify-self-stretch overflow-hidden">
<!-- show giver and/or receiver profiles... which seemed like a good idea but actually adds clutter
<span
v-if="
record.giver.profileImageUrl ||
record.receiver.profileImageUrl
"
>
<EntityIcon
v-if="record.agentDid !== activeDid"
:icon-size="32"
:profile-image-url="record.giver.profileImageUrl"
class="inline-block align-middle border border-slate-300 rounded-md mr-1"
/>
<font-awesome
v-if="
record.agentDid !== activeDid &&
record.recipientDid !== activeDid &&
!record.fulfillsPlanHandleId
"
icon="ellipsis"
class="text-slate"
/>
<EntityIcon
v-if="
record.recipientDid !== activeDid &&
!record.fulfillsPlanHandleId
"
:iconSize="32"
:profile-image-url="record.receiver.profileImageUrl"
class="inline-block align-middle border border-slate-300 rounded-md ml-1"
/>
</span>
-->
<span class="pl-2 block break-words">
{{ giveDescription(record) }}
</span>
@@ -447,7 +419,7 @@ interface GiveRecordWithContactInfo extends GiveSummaryRecord {
profileImageUrl?: string;
};
}
import { logger } from "../utils/logger";
/**
* HomeView - Main view component for the application's home page
*
@@ -530,7 +502,7 @@ export default class HomeView extends Vue {
await this.loadFeedData();
await this.loadNewOffers();
await this.checkOnboarding();
} catch (err: any) {
} catch (err: unknown) {
this.handleError(err);
}
}
@@ -675,7 +647,7 @@ export default class HomeView extends Vue {
* - Displays user notification
* @param err Error object with optional userMessage
*/
private handleError(err: any) {
private handleError(err: unknown) {
logConsoleAndDb("Error retrieving settings or feed: " + err, true);
this.$notify(
{
@@ -857,7 +829,7 @@ export default class HomeView extends Vue {
}
})
.catch((e) => {
console.error("Error with feed load:", e);
logger.error("Error with feed load:", e);
this.$notify(
{
group: "alert",
@@ -1098,7 +1070,7 @@ export default class HomeView extends Vue {
// The Web Share API will handle sharing the URL appropriately
this.imageCache.set(imageUrl, null);
} catch (error) {
console.warn("Failed to cache image:", error);
logger.warn("Failed to cache image:", error);
}
}

View File

@@ -113,7 +113,7 @@ import {
} from "../db/index";
import { MASTER_SETTINGS_KEY } from "../db/tables/settings";
import { retrieveAllAccountsMetadata } from "../libs/util";
import { logger } from "../utils/logger";
@Component({ components: { QuickNav } })
export default class IdentitySwitcherView extends Vue {
$notify!: (notification: NotificationIface, timeout?: number) => void;
@@ -153,7 +153,7 @@ export default class IdentitySwitcherView extends Vue {
},
5000,
);
console.error("Telling user to clear cache at page create because:", err);
logger.error("Telling user to clear cache at page create because:", err);
}
}

View File

@@ -99,7 +99,7 @@ import {
newIdentifier,
} from "../libs/crypto";
import { retrieveAccountCount } from "../libs/util";
import { logger } from "../utils/logger";
@Component({
components: {},
})
@@ -174,7 +174,7 @@ export default class ImportAccountView extends Vue {
this.$router.push({ name: "account" });
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (err: any) {
console.error("Error saving mnemonic & updating settings:", err);
logger.error("Error saving mnemonic & updating settings:", err);
if (err == "Error: invalid mnemonic") {
this.$notify(
{

View File

@@ -81,7 +81,7 @@ import {
import { accountsDBPromise, db } from "../db/index";
import { MASTER_SETTINGS_KEY } from "../db/tables/settings";
import { retrieveAllFullyDecryptedAccounts } from "../libs/util";
import { logger } from "../utils/logger";
@Component({
components: {},
})
@@ -156,7 +156,7 @@ export default class ImportAccountView extends Vue {
});
this.$router.push({ name: "account" });
} catch (err) {
console.error("Error saving mnemonic & updating settings:", err);
logger.error("Error saving mnemonic & updating settings:", err);
}
}
}

View File

@@ -142,7 +142,7 @@ import { APP_SERVER, AppString, NotificationIface } from "../constants/app";
import { db, retrieveSettingsForActiveAccount } from "../db/index";
import { Contact } from "../db/tables/contacts";
import { createInviteJwt, getHeaders } from "../libs/endorserServer";
import { logger } from "../utils/logger";
interface Invite {
inviteIdentifier: string;
expiresAt: string;
@@ -191,7 +191,7 @@ export default class InviteOneView extends Vue {
}
}
} catch (error) {
console.error("Error fetching invites:", error);
logger.error("Error fetching invites:", error);
this.$notify(
{
group: "alert",
@@ -258,7 +258,7 @@ export default class InviteOneView extends Vue {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
lookForErrorAndNotify(error: any, title: string, defaultMessage: string) {
console.error(title, "-", error);
logger.error(title, "-", error);
let message = defaultMessage;
if (error.response && error.response.data && error.response.data.error) {
if (error.response.data.error.message) {

View File

@@ -224,7 +224,7 @@ export default class NewActivityView extends Vue {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (err: any) {
console.error("Error retrieving settings & contacts:", err);
logger.error("Error retrieving settings & contacts:", err);
this.$notify(
{
group: "alert",

View File

@@ -187,13 +187,6 @@
@click.stop="showNostrPartnerInfo"
/>
</div>
<!--
<div class="flex" @click="sendToTripHopping = !sendToTripHopping">
<input type="checkbox" class="mr-2" v-model="sendToTripHopping" />
<label>Send to TripHopping</label>
<font-awesome icon="circle-info" class="text-blue-500 ml-2 cursor-pointer" @click.stop="showNostrPartnerInfo" />
</div>
-->
</div>
<div class="mt-8">
@@ -261,7 +254,7 @@ import {
VerifiedEvent,
} from "nostr-tools/lib/esm/index.js";
import { serializeEvent } from "nostr-tools/lib/esm/index.js";
import { logger } from "../utils/logger";
@Component({
components: { ImageMethodDialog, LMap, LMarker, LTileLayer, QuickNav },
})
@@ -364,7 +357,7 @@ export default class NewEditProjectView extends Vue {
}
}
} catch (error) {
console.error("Got error retrieving that project", error);
logger.error("Got error retrieving that project", error);
this.errNote("There was an error retrieving that project.");
}
}
@@ -398,7 +391,7 @@ export default class NewEditProjectView extends Vue {
window.location.hostname === "localhost" &&
!DEFAULT_IMAGE_API_SERVER.includes("localhost")
) {
console.log(
logger.log(
"Using shared image API server, so only users on that server can play with images.",
);
}
@@ -412,7 +405,7 @@ export default class NewEditProjectView extends Vue {
// don't bother with a notification
// (either they'll simply continue or they're canceling and going back)
} else {
console.error("Problem deleting image:", response);
logger.error("Problem deleting image:", response);
this.$notify(
{
group: "alert",
@@ -427,10 +420,10 @@ export default class NewEditProjectView extends Vue {
this.imageUrl = "";
} catch (error) {
console.error("Error deleting image:", error);
logger.error("Error deleting image:", error);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
if ((error as any).response.status === 404) {
console.log("The image was already deleted:", error);
logger.log("The image was already deleted:", error);
this.imageUrl = "";
@@ -602,10 +595,7 @@ export default class NewEditProjectView extends Vue {
this.$router.push({ path: "/project/" + projectPath });
} else {
console.error(
"Got unexpected 'data' inside response from server",
resp,
);
logger.error("Got unexpected 'data' inside response from server", resp);
this.$notify(
{
group: "alert",
@@ -622,7 +612,7 @@ export default class NewEditProjectView extends Vue {
error?: { message?: string };
}>;
if (serverError) {
console.error("Got error from server", serverError);
logger.error("Got error from server", serverError);
if (Object.prototype.hasOwnProperty.call(serverError, "message")) {
userMessage =
(serverError.response?.data?.error?.message as string) ||
@@ -648,7 +638,7 @@ export default class NewEditProjectView extends Vue {
);
}
} else {
console.error("Here's the full error trying to save the claim:", error);
logger.error("Here's the full error trying to save the claim:", error);
this.$notify(
{
group: "alert",
@@ -768,7 +758,7 @@ export default class NewEditProjectView extends Vue {
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (error: any) {
console.error(`Error sending to ${serviceName}`, error);
logger.error(`Error sending to ${serviceName}`, error);
let errorMessage = `There was an error sending to ${serviceName}.`;
if (error.response?.data?.error?.message) {
errorMessage = error.response.data.error.message;
@@ -790,7 +780,7 @@ export default class NewEditProjectView extends Vue {
this.isHiddenSpinner = false;
if (this.numAccounts === 0) {
console.error("Error: there is no account.");
logger.error("Error: there is no account.");
} else {
this.saveProject();
}

View File

@@ -192,7 +192,7 @@ import {
} from "../libs/endorserServer";
import * as libsUtil from "../libs/util";
import { retrieveAccountDids } from "../libs/util";
import { logger } from "../utils/logger";
/**
* Offer Details View Component
* @author Matthew Raymer
@@ -303,8 +303,8 @@ export default class OfferDetailsView extends Vue {
await this.loadAccountSettings();
await this.loadRecipientInfo();
await this.loadProjectInfo();
} catch (err: any) {
console.error("Error in mounted:", err);
} catch (err: unknown) {
logger.error("Error in mounted:", err);
this.$notify(
{
group: "alert",
@@ -328,7 +328,7 @@ export default class OfferDetailsView extends Vue {
this.$route.query["prevCredToEdit"] as string,
) as GenericCredWrapper<OfferVerifiableCredential>)
: undefined;
} catch (error) {
} catch (error: unknown) {
this.$notify(
{
group: "alert",
@@ -687,7 +687,7 @@ export default class OfferDetailsView extends Vue {
if (result.type === "error" || this.isCreationError(result.response)) {
const errorMessage = this.getCreationErrorMessage(result);
console.error("Error with offer creation result:", result);
logger.error("Error with offer creation result:", result);
this.$notify(
{
group: "alert",
@@ -716,7 +716,7 @@ export default class OfferDetailsView extends Vue {
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (error: any) {
console.error("Error with offer recordation caught:", error);
logger.error("Error with offer recordation caught:", error);
const errorMessage =
error.userMessage ||
error.response?.data?.error?.message ||

View File

@@ -99,7 +99,10 @@
<h2 class="text-2xl mb-4">
{{ isInCreateMode() ? "Create New Meeting" : "Edit Meeting" }}
</h2>
<!-- This is my first form. Not sure if I like it; will see if the browser benefits extend to the native app. -->
<!--
This is my first form. Not sure if I like it; will see if the browser benefits extend to
the native app.
-->
<form
class="space-y-4"
@submit.prevent="isInCreateMode() ? createMeeting() : updateMeeting()"
@@ -236,7 +239,7 @@ import {
serverMessageForUser,
} from "../libs/endorserServer";
import { encryptMessage } from "../libs/crypto";
import { logger } from "../utils/logger";
interface ServerMeeting {
groupId: number; // from the server
name: string; // from the server
@@ -512,7 +515,7 @@ export default class OnboardMeetingView extends Vue {
3000,
);
} catch (error) {
console.error("Error deleting meeting:", error);
logger.error("Error deleting meeting:", error);
this.$notify(
{
group: "alert",
@@ -538,7 +541,7 @@ export default class OnboardMeetingView extends Vue {
password: this.currentMeeting.password || "",
};
} else {
console.error(
logger.error(
"There is no current meeting to edit. We should never get here.",
);
}

View File

@@ -159,7 +159,10 @@
<h3 class="text-sm uppercase font-semibold mt-3">
Projects That Contribute To This
</h3>
<!-- centering because long, wrapped project names didn't left align with blank or "text-left" -->
<!--
centering because long, wrapped project names didn't left align with blank
or "text-left"
-->
<div class="text-center">
<div v-for="plan in fulfillersToThis" :key="plan.handleId">
<button
@@ -181,7 +184,10 @@
<h3 class="text-sm uppercase font-semibold mb-3">
Projects Getting Contributions From This
</h3>
<!-- centering because long, wrapped project names didn't left align with blank or "text-left" -->
<!--
centering because long, wrapped project names didn't left align with blank
or "text-left"
-->
<div class="text-center">
<button
class="text-blue-500"
@@ -372,8 +378,8 @@
<span class="font-semibold mr-2 shrink-0">Totals</span>
<span class="whitespace-nowrap overflow-hidden text-ellipsis">
<a
@click="totalsExpanded = !totalsExpanded"
class="cursor-pointer text-blue-500"
@click="totalsExpanded = !totalsExpanded"
>
<!-- just show the hours, or alternatively whatever is first -->
<span v-if="givenTotalHours() > 0">
@@ -623,7 +629,7 @@ import * as libsUtil from "../libs/util";
import * as serverUtil from "../libs/endorserServer";
import { retrieveAccountDids } from "../libs/util";
import HiddenDidDialog from "../components/HiddenDidDialog.vue";
import { logger } from "../utils/logger";
/**
* Project View Component
* @author Matthew Raymer
@@ -702,6 +708,7 @@ export default class ProjectViewView extends Vue {
fulfillersToThis: Array<PlanSummaryRecord> = [];
/** Flag for fulfiller pagination */
fulfillersToHitLimit = false;
/** Gifts to this project */
givesToThis: Array<GiveSummaryRecord> = [];
givesHitLimit = false;
givesProvidedByThis: Array<GiveSummaryRecord> = [];
@@ -733,14 +740,6 @@ export default class ProjectViewView extends Vue {
// Interaction Data
/** Gifts to this project */
givesToThis: Array<GiveSummaryRecord> = [];
/** Flag for gifts pagination */
givesHitLimit = false;
/** Gifts from this project */
givesProvidedByThis: Array<GiveSummaryRecord> = [];
/** Flag for provided gifts pagination */
givesProvidedByHitLimit = false;
/** Offers to this project */
offersToThis: Array<OfferSummaryRecord> = [];
/** Flag for offers pagination */
offersHitLimit = false;
@@ -750,7 +749,7 @@ export default class ProjectViewView extends Vue {
checkingConfirmationForJwtId = "";
/** Recently checked unconfirmable JWTs */
recentlyCheckedAndUnconfirmableJwts: string[] = [];
startTime = "";
totalsExpanded = false;
truncatedDesc = "";
/** Truncation length */
@@ -806,12 +805,14 @@ export default class ProjectViewView extends Vue {
this.loadTotals();
}
onEditClick() {
const route = {
/**
* Navigates to project edit view with current project ID
*/
onEditClick(): void {
this.$router.push({
name: "new-edit-project",
query: { projectId: this.projectId },
};
(this.$router as Router).push(route);
});
}
// Isn't there a better way to make this available to the template?
@@ -869,7 +870,7 @@ export default class ProjectViewView extends Vue {
this.url = resp.data.claim?.url || "";
} else {
// actually, axios throws an error on 404 so we probably never get here
console.error("Error getting project:", resp);
logger.error("Error getting project:", resp);
this.$notify(
{
group: "alert",
@@ -881,7 +882,7 @@ export default class ProjectViewView extends Vue {
);
}
} catch (error: unknown) {
console.error("Error retrieving project:", error);
logger.error("Error retrieving project:", error);
this.$notify(
{
group: "alert",
@@ -958,7 +959,7 @@ export default class ProjectViewView extends Vue {
},
5000,
);
console.error(
logger.error(
"Something went wrong retrieving more gives to this project:",
serverError.message,
);
@@ -1017,7 +1018,7 @@ export default class ProjectViewView extends Vue {
},
5000,
);
console.error(
logger.error(
"Something went wrong retrieving gives that were provided by this project:",
serverError.message,
);
@@ -1073,7 +1074,7 @@ export default class ProjectViewView extends Vue {
},
5000,
);
console.error(
logger.error(
"Something went wrong retrieving more offers to this project:",
serverError.message,
);
@@ -1129,7 +1130,7 @@ export default class ProjectViewView extends Vue {
},
5000,
);
console.error(
logger.error(
"Something went wrong retrieving more plans that fulfill this project:",
serverError.message,
);
@@ -1176,30 +1177,13 @@ export default class ProjectViewView extends Vue {
},
5000,
);
console.error(
logger.error(
"Error retrieving plans fulfilled by this project:",
serverError.message,
);
}
}
onEditClick() {
const route = {
name: "new-edit-project",
query: { projectId: this.projectId },
};
this.$router.push(route);
}
// Isn't there a better way to make this available to the template?
expandText() {
this.expanded = true;
}
collapseText() {
this.expanded = false;
}
/**
* Handle clicking on a project entry found in the list
* @param id of the project
@@ -1437,7 +1421,7 @@ export default class ProjectViewView extends Vue {
give.jwtId,
];
} else {
console.error("Got error submitting the confirmation:", result);
logger.error("Got error submitting the confirmation:", result);
const message =
(result.error?.error as string) ||
"There was a problem submitting the confirmation.";
@@ -1493,7 +1477,7 @@ export default class ProjectViewView extends Vue {
);
}
} catch (error) {
console.error("Error loading totals:", error);
logger.error("Error loading totals:", error);
this.$notify(
{
group: "alert",

View File

@@ -159,7 +159,8 @@
>
<!--
There's no need for a green icon:
it's unnecessary if there's already a green, and confusing if there's a yellow.
it's unnecessary if there's already a green, and confusing if there's a
yellow.
-->
all
</span>
@@ -287,7 +288,7 @@ import {
} from "../libs/endorserServer";
import * as libsUtil from "../libs/util";
import { OnboardPage } from "../libs/util";
import { logger } from "../utils/logger";
@Component({
components: {
EntityIcon,
@@ -345,13 +346,13 @@ export default class ProjectsView extends Vue {
}
if (this.allMyDids.length === 0) {
console.error("No accounts found.");
logger.error("No accounts found.");
this.errNote("You need an identifier to load your projects.");
} else {
await this.loadProjects();
}
} catch (err) {
console.error("Error initializing:", err);
logger.error("Error initializing:", err);
this.errNote("Something went wrong loading your projects.");
}
}
@@ -380,7 +381,7 @@ export default class ProjectsView extends Vue {
});
}
} else {
console.error(
logger.error(
"Bad server response & data for plans:",
resp.status,
resp.data,
@@ -389,7 +390,7 @@ export default class ProjectsView extends Vue {
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (error: any) {
console.error("Got error loading plans:", error.message || error);
logger.error("Got error loading plans:", error.message || error);
this.errNote("Got an error loading projects.");
} finally {
this.isLoading = false;
@@ -473,7 +474,7 @@ export default class ProjectsView extends Vue {
this.offers = this.offers.concat([offer]);
}
} else {
console.error(
logger.error(
"Bad server response & data for offers:",
resp.status,
resp.data,
@@ -490,7 +491,7 @@ export default class ProjectsView extends Vue {
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (error: any) {
console.error("Got error loading offers:", error.message || error);
logger.error("Got error loading offers:", error.message || error);
this.$notify(
{
group: "alert",

View File

@@ -81,7 +81,7 @@ import {
createAndSubmitGive,
} from "../libs/endorserServer";
import * as libsUtil from "../libs/util";
import { logger } from "../utils/logger";
@Component({
components: {
QuickNav,
@@ -143,7 +143,7 @@ export default class QuickActionBvcBeginView extends Vue {
if (timeResult.type === "success") {
timeSuccess = true;
} else {
console.error("Error sending time:", timeResult);
logger.error("Error sending time:", timeResult);
this.$notify(
{
group: "alert",
@@ -170,7 +170,7 @@ export default class QuickActionBvcBeginView extends Vue {
if (attendResult.type === "success") {
attendedSuccess = true;
} else {
console.error("Error sending attendance:", attendResult);
logger.error("Error sending attendance:", attendResult);
this.$notify(
{
group: "alert",
@@ -206,7 +206,7 @@ export default class QuickActionBvcBeginView extends Vue {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (error: any) {
console.error("Error sending claims.", error);
logger.error("Error sending claims.", error);
this.$notify(
{
group: "alert",

View File

@@ -164,7 +164,7 @@ import {
createAndSubmitGive,
getHeaders,
} from "../libs/endorserServer";
import { logger } from "../utils/logger";
@Component({
methods: { claimSpecialDescription },
components: {
@@ -229,7 +229,7 @@ export default class QuickActionBvcBeginView extends Vue {
);
if (!response.ok) {
console.error("Bad response", response);
logger.error("Bad response", response);
throw new Error("Bad response when retrieving claims.");
}
await response.json().then((data) => {
@@ -248,7 +248,7 @@ export default class QuickActionBvcBeginView extends Vue {
dataByOthers.length - dataByOthersWithoutHidden.length;
});
} catch (error) {
console.error("Error:", error);
logger.error("Error:", error);
this.$notify(
{
group: "alert",
@@ -300,7 +300,7 @@ export default class QuickActionBvcBeginView extends Vue {
result.status === "fulfilled" && result.value.type === "success",
);
if (confirmsSucceeded.length < this.claimsToConfirmSelected.length) {
console.error("Error sending confirmations:", confirmResults);
logger.error("Error sending confirmations:", confirmResults);
const howMany = confirmsSucceeded.length === 0 ? "all" : "some";
this.$notify(
{
@@ -333,7 +333,7 @@ export default class QuickActionBvcBeginView extends Vue {
);
giveSucceeded = giveResult.type === "success";
if (!giveSucceeded) {
console.error("Error sending give:", giveResult);
logger.error("Error sending give:", giveResult);
this.$notify(
{
group: "alert",
@@ -405,7 +405,7 @@ export default class QuickActionBvcBeginView extends Vue {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (error: any) {
console.error("Error sending claims.", error);
logger.error("Error sending claims.", error);
this.$notify(
{
group: "alert",

View File

@@ -94,7 +94,7 @@ import {
getNewOffersToUserProjects,
} from "../libs/endorserServer";
import { retrieveAccountDids } from "../libs/util";
import { logger } from "../utils/logger";
@Component({
components: { EntityIcon, GiftedDialog, InfiniteScroll, QuickNav },
})
@@ -138,7 +138,7 @@ export default class RecentOffersToUserView extends Vue {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (err: any) {
console.error("Error retrieving settings & contacts:", err);
logger.error("Error retrieving settings & contacts:", err);
this.$notify(
{
group: "alert",

View File

@@ -86,7 +86,7 @@ import {
getNewOffersToUser,
} from "../libs/endorserServer";
import { retrieveAccountDids } from "../libs/util";
import { logger } from "../utils/logger";
@Component({
components: { EntityIcon, GiftedDialog, InfiniteScroll, QuickNav },
})
@@ -129,7 +129,7 @@ export default class RecentOffersToUserView extends Vue {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (err: any) {
console.error("Error retrieving settings & contacts:", err);
logger.error("Error retrieving settings & contacts:", err);
this.$notify(
{
group: "alert",

View File

@@ -115,7 +115,7 @@ import QuickNav from "../components/QuickNav.vue";
import { NotificationIface } from "../constants/app";
import { db, retrieveSettingsForActiveAccount } from "../db/index";
import { BoundingBox, MASTER_SETTINGS_KEY } from "../db/tables/settings";
import { logger } from "../utils/logger";
const DEFAULT_LAT_LONG_DIFF = 0.01;
const WORLD_ZOOM = 2;
const DEFAULT_ZOOM = 2;
@@ -231,7 +231,7 @@ export default class SearchAreaView extends Vue {
},
5000,
);
console.error(
logger.error(
"Telling user to retry the location search setting because:",
err,
);
@@ -274,7 +274,7 @@ export default class SearchAreaView extends Vue {
},
5000,
);
console.error(
logger.error(
"Telling user to retry the location search setting because:",
err,
);

View File

@@ -117,6 +117,7 @@ import {
retrieveFullyDecryptedAccount,
} from "../libs/util";
import { Router } from "vue-router";
import { logger } from "../utils/logger";
@Component({ components: { QuickNav } })
export default class SeedBackupView extends Vue {
$notify!: (notification: NotificationIface, timeout?: number) => void;
@@ -136,7 +137,7 @@ export default class SeedBackupView extends Vue {
this.numAccounts = await retrieveAccountCount();
this.activeAccount = await retrieveFullyDecryptedAccount(activeDid);
} catch (err: unknown) {
console.error("Got an error loading an identifier:", err);
logger.error("Got an error loading an identifier:", err);
this.$notify(
{
group: "alert",

View File

@@ -50,7 +50,7 @@ import { NotificationIface, APP_SERVER } from "../constants/app";
import { db, retrieveSettingsForActiveAccount } from "../db/index";
import { retrieveAccountMetadata } from "../libs/util";
import { generateEndorserJwtUrlForAccount } from "../libs/endorserServer";
import { logger } from "../utils/logger";
@Component({
components: { QuickNav, TopMessage },
})
@@ -59,7 +59,7 @@ export default class ShareMyContactInfoView extends Vue {
$router!: Router;
mounted() {
console.log("APP_SERVER in mounted:", APP_SERVER);
logger.log("APP_SERVER in mounted:", APP_SERVER);
}
async onClickShare() {

View File

@@ -83,7 +83,7 @@ import { db, retrieveSettingsForActiveAccount } from "../db/index";
import { MASTER_SETTINGS_KEY } from "../db/tables/settings";
import { accessToken } from "../libs/crypto";
import { base64ToBlob, SHARED_PHOTO_BASE64_KEY } from "../libs/util";
import { logger } from "../utils/logger";
@Component({ components: { PhotoDialog, QuickNav } })
export default class SharedPhotoView extends Vue {
$notify!: (notification: NotificationIface, timeout?: number) => void;
@@ -113,10 +113,10 @@ export default class SharedPhotoView extends Vue {
this.imageFileName = this.$route.query["fileName"] as string;
} else {
console.error("No appropriate image found in temp storage.", temp);
logger.error("No appropriate image found in temp storage.", temp);
}
} catch (err: unknown) {
console.error("Got an error loading an identifier:", err);
logger.error("Got an error loading an identifier:", err);
this.$notify(
{
group: "alert",
@@ -191,7 +191,7 @@ export default class SharedPhotoView extends Vue {
window.location.hostname === "localhost" &&
!DEFAULT_IMAGE_API_SERVER.includes("localhost")
) {
console.log(
logger.log(
"Using shared image API server, so only users on that server can play with images.",
);
}
@@ -205,7 +205,7 @@ export default class SharedPhotoView extends Vue {
this.imageFileName = undefined;
result = response.data.url as string;
} else {
console.error("Problem uploading the image", response.data);
logger.error("Problem uploading the image", response.data);
this.$notify(
{
group: "alert",
@@ -221,7 +221,7 @@ export default class SharedPhotoView extends Vue {
this.uploading = false;
} catch (error) {
console.error("Error uploading the image", error);
logger.error("Error uploading the image", error);
this.$notify(
{
group: "alert",

View File

@@ -285,7 +285,7 @@ import {
registerAndSavePasskey,
SHARED_PHOTO_BASE64_KEY,
} from "../libs/util";
import { logger } from "../utils/logger";
const inputFileNameRef = ref<Blob>();
const TEST_PAYLOAD = {
@@ -411,7 +411,7 @@ export default class Help extends Vue {
TEST_PAYLOAD,
this.credIdHex as string,
);
console.log("simple jwt4url", this.jwt);
logger.log("simple jwt4url", this.jwt);
}
public async createJwtNavigator() {
@@ -428,7 +428,7 @@ export default class Help extends Vue {
TEST_PAYLOAD,
this.credIdHex as string,
);
console.log("lower jwt4url", this.jwt);
logger.log("lower jwt4url", this.jwt);
}
public async verifyP256() {
@@ -440,7 +440,7 @@ export default class Help extends Vue {
this.peerSetup?.clientDataJsonBase64Url as Base64URLString,
this.peerSetup?.signature as Base64URLString,
);
console.log("decoded", decoded);
logger.log("decoded", decoded);
}
public async verifySimplewebauthn() {
@@ -452,7 +452,7 @@ export default class Help extends Vue {
this.peerSetup?.clientDataJsonBase64Url as Base64URLString,
this.peerSetup?.signature as Base64URLString,
);
console.log("decoded", decoded);
logger.log("decoded", decoded);
}
public async verifyWebCrypto() {
@@ -464,7 +464,7 @@ export default class Help extends Vue {
this.peerSetup?.clientDataJsonBase64Url as Base64URLString,
this.peerSetup?.signature as Base64URLString,
);
console.log("decoded", decoded);
logger.log("decoded", decoded);
}
public async verifyMyJwt() {
@@ -490,7 +490,7 @@ export default class Help extends Vue {
payload["ClientDataJSONB64URL"],
signatureB64URL,
);
console.log("decoded", decoded);
logger.log("decoded", decoded);
}
}
</script>

View File

@@ -108,7 +108,7 @@ import { Contact } from "../db/tables/contacts";
import { didInfo, getHeaders } from "../libs/endorserServer";
import { UserProfile } from "../libs/partnerServer";
import { retrieveAccountDids } from "../libs/util";
import { logger } from "../utils/logger";
@Component({
components: {
LMap,
@@ -169,7 +169,7 @@ export default class UserProfileView extends Vue {
throw new Error("Failed to load profile");
}
} catch (error) {
console.error("Error loading profile:", error);
logger.error("Error loading profile:", error);
this.$notify(
{
group: "alert",