Skip to content

Commit

Permalink
Update type definitions.
Browse files Browse the repository at this point in the history
  • Loading branch information
tmpfs committed Dec 10, 2024
1 parent d62c232 commit b751396
Show file tree
Hide file tree
Showing 4 changed files with 289 additions and 51 deletions.
24 changes: 21 additions & 3 deletions crates/ipc/src/web_service/secret.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
//! Server for the native messaging API bridge.
use http::{Request, Response, StatusCode};
use serde::Deserialize;
use sos_sdk::prelude::{Account, SecretPath};

use crate::web_service::{
json, parse_account_id, parse_json_body, status, Accounts, Body, Incoming,
};

#[derive(Deserialize)]
struct CopyRequest {
target: SecretPath,
path: Option<String>,
}

/// Copy a secret to the clipboard.
#[cfg(feature = "clipboard")]
pub async fn copy_secret_clipboard<A, R, E>(
Expand All @@ -22,19 +29,30 @@ where
+ From<std::io::Error>
+ 'static,
{
use sos_sdk::json_path::JsonPath;

use crate::web_service::internal_server_error;

let Some(account_id) = parse_account_id(&req) else {
return status(StatusCode::BAD_REQUEST);
};

let Ok(request) = parse_json_body::<SecretPath>(req).await else {
let Ok(request) = parse_json_body::<CopyRequest>(req).await else {
return status(StatusCode::BAD_REQUEST);
};

let path = None;
let path = if let Some(path) = &request.path {
let Ok(path) = JsonPath::parse(path) else {
return internal_server_error("json_path::parse");
};
Some(path)
} else {
None
};

let accounts = accounts.read().await;
match accounts
.copy_clipboard(&account_id, &request, path.as_ref())
.copy_clipboard(&account_id, &request.target, path.as_ref())
.await
{
Ok(result) => json(StatusCode::OK, &result),
Expand Down
49 changes: 5 additions & 44 deletions crates/sdk/src/vault/secret.rs
Original file line number Diff line number Diff line change
Expand Up @@ -745,7 +745,9 @@ impl UserData {
}

/// Enumeration of types of identification.
#[derive(PartialEq, Eq, Clone)]
#[typeshare::typeshare]
#[derive(PartialEq, Eq, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub enum IdentityKind {
/// Personal identification number (PIN).
PersonalIdNumber,
Expand Down Expand Up @@ -818,48 +820,6 @@ impl TryFrom<u8> for IdentityKind {
}
}

impl Serialize for IdentityKind {
fn serialize<S>(
&self,
serializer: S,
) -> std::result::Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_u8(self.into())
}
}

impl<'de> Deserialize<'de> for IdentityKind {
fn deserialize<D>(
deserializer: D,
) -> std::result::Result<IdentityKind, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_u8(IdentityKindVisitor)
}
}

struct IdentityKindVisitor;

impl<'de> Visitor<'de> for IdentityKindVisitor {
type Value = IdentityKind;

fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter
.write_str("an integer between 0 and 255 for identification kind")
}

fn visit_u8<E>(self, value: u8) -> std::result::Result<Self::Value, E>
where
E: de::Error,
{
let value: IdentityKind = value.try_into().unwrap();
Ok(value)
}
}

/// Enumeration of AGE versions.
#[derive(Default, Clone, Serialize, Deserialize, Eq, PartialEq)]
pub enum AgeVersion {
Expand Down Expand Up @@ -1075,8 +1035,9 @@ impl Clone for FileContent {
/// * `PathBuf` -> `Secret::File`
/// * `Url` -> `Secret::Link`
///
#[typeshare::typeshare]
#[derive(Serialize, Deserialize)]
#[serde(untagged, rename_all = "lowercase")]
#[serde(rename_all = "camelCase", tag = "kind", content = "body")]
pub enum Secret {
/// A UTF-8 encoded note.
#[serde(rename_all = "camelCase")]
Expand Down
225 changes: 223 additions & 2 deletions packages/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,14 @@ export type VaultFlags = number;
export type SecretId = string;
export type Cipher = string;
export type KeyDerivation = string;
export type AuthenticatedList = [string, boolean][]
export type SecretBox<T> = T;
export type Set<T> = T[];
export type SecretString = SecretBox<string>;
export type Pem = string;
export type Vcard = never;
export type SecretSigner = never;
export type AgeVersion = never;
export type TOTP = never;

// Internally this is a HashMap but we can't serialize
// that to JSON so for Javascript it's just an array
Expand All @@ -21,11 +28,42 @@ export type AccountState = PublicIdentity;

export type FolderInfo = Summary;
export interface FoldersList {
[accountId: string]: FolderInfo;
[accountId: string]: FolderInfo[];
}
export interface SearchResults {
[accountId: string]: DocumentsList;
}

export interface AuthenticatedList{
[accountId: string]: boolean;
}

export enum Kind {
Individual = "individual",
Group = "group",
Org = "org",
Location = "location",
}

type BodyOf<T extends { kind: string; body: unknown }, K extends T["kind"]> =
T extends { kind: K } ? T["body"] : never;

type NoteSecret = BodyOf<Secret, "note">;
type FileSecret = BodyOf<Secret, "file">;
type AccountSecret = BodyOf<Secret, "account">;
type ListSecret = BodyOf<Secret, "list">;
type PemSecret = BodyOf<Secret, "pem">;
type PageSecret = BodyOf<Secret, "page">;
type SignerSecret = BodyOf<Secret, "signer">;
type ContactSecret = BodyOf<Secret, "contact">;
type TotpSecret = BodyOf<Secret, "totp">;
type CardSecret = BodyOf<Secret, "card">;
type BankSecret = BodyOf<Secret, "bank">;
type LinkSecret = BodyOf<Secret, "link">;
type PasswordSecret = BodyOf<Secret, "password">;
type IdentitySecret = BodyOf<Secret, "identity">;
type AgeSecret = BodyOf<Secret, "age">;

/*
Generated by typeshare 1.12.0
*/
Expand Down Expand Up @@ -219,6 +257,171 @@ export interface QueryFilter {
types: SecretType[];
}

/**
* Represents the various types of secret.
*
* Some variants can be created from other types
* using a `From` or `TryFrom` implementation:
*
* * `String` -> `Secret::Note`
* * `HashMap<String, SecretString>` -> `Secret::List`
* * `SecretString` -> `Secret::Password`
* * `PathBuf` -> `Secret::File`
* * `Url` -> `Secret::Link`
*
*/
export type Secret =
/** A UTF-8 encoded note. */
| { kind: "note", body: {
/** Note text. */
text: SecretString;
/** Custom user data. */
userData?: UserData;
}}
/** A binary blob. */
| { kind: "file", body: {
/** File secret data. */
content: FileContent;
/** Custom user data. */
userData?: UserData;
}}
/** Account with login password. */
| { kind: "account", body: {
/** Name of the account. */
account: string;
/** The account password. */
password: SecretString;
/** Optional URLs associated with the account. */
url: string[];
/** Custom user data. */
userData?: UserData;
}}
/** Collection of credentials as key/value pairs. */
| { kind: "list", body: {
/** The items in the list. */
items: Record<string, SecretString>;
/** Custom user data. */
userData?: UserData;
}}
/** PEM encoded binary data. */
| { kind: "pem", body: {
/** Collection of PEM encoded certificates or keys. */
certificates: Pem[];
/** Custom user data. */
userData?: UserData;
}}
/** A UTF-8 text document. */
| { kind: "page", body: {
/** Title of the page. */
title: string;
/** Mime type for the text, default is `text/markdown`. */
mime: string;
/** The binary data. */
document: SecretString;
/** Custom user data. */
userData?: UserData;
}}
/** Private signing key. */
| { kind: "signer", body: {
/** The private key. */
privateKey: SecretSigner;
/** Custom user data. */
userData?: UserData;
}}
/** Contact for an organization or person. */
| { kind: "contact", body: {
/** The contact vCard. */
vcard: Vcard;
/** Custom user data. */
userData?: UserData;
}}
/** Two-factor authentication using a TOTP. */
| { kind: "totp", body: {
/** Time-based one-time passcode. */
totp: TOTP;
/** Custom user data. */
userData?: UserData;
}}
/** Credit or debit card. */
| { kind: "card", body: {
/** The card number. */
number: SecretString;
/** The expiry data for the card. */
expiry?: string;
/** Card verification value. */
cvv: SecretString;
/** Name that appears on the card. */
name?: SecretString;
/** ATM PIN. */
atmPin?: SecretString;
/** Custom user data. */
userData?: UserData;
}}
/** Bank account. */
| { kind: "bank", body: {
/** The account number. */
number: SecretString;
/** The routing number (US) or sort code (UK). */
routing: SecretString;
/** IBAN. */
iban?: SecretString;
/** SWIFT. */
swift?: SecretString;
/** BIC. */
bic?: SecretString;
/** Custom user data. */
userData?: UserData;
}}
/** External link; intended to be used in embedded user fields. */
| { kind: "link", body: {
/** External link URL. */
url: SecretString;
/** Optional label for the link. */
label?: SecretString;
/** Optional title for the link. */
title?: SecretString;
/** Custom user data. */
userData?: UserData;
}}
/** Standalone password; intended to be used in embedded user fields. */
| { kind: "password", body: {
/** Password secret. */
password: SecretString;
/**
* Optional name for the password.
*
* This could be a username, account name or other label
* the user wants to associate with this password.
*/
name?: SecretString;
/** Custom user data. */
userData?: UserData;
}}
/** Identity secret for passports, driving licenses etc. */
| { kind: "identity", body: {
/** The kind of this identification. */
idKind: IdentityKind;
/** The number for the identifier. */
number: SecretString;
/** Issue place. */
issuePlace?: string;
/** Issue date. */
issueDate?: string;
/** Expiration date. */
expiryDate?: string;
/** Custom user data. */
userData?: UserData;
}}
/** AGE encryption standard. */
| { kind: "age", body: {
/** The version of AGE. */
version: AgeVersion;
/** Secret key for the AGE identity. */
key: SecretString;
/** Custom user data. */
userData?: UserData;
}};

/** Secret with it's associated meta data and identifier. */
export interface SecretRow {
/** Identifier for the secret. */
Expand Down Expand Up @@ -369,3 +572,21 @@ export type FileContent =
checksum: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number];
}};

/** Enumeration of types of identification. */
export enum IdentityKind {
/** Personal identification number (PIN). */
PersonalIdNumber = "personalIdNumber",
/** Generic id card. */
IdCard = "idCard",
/** Passport identification. */
Passport = "passport",
/** Driver license identification. */
DriverLicense = "driverLicense",
/** Social security identification. */
SocialSecurity = "socialSecurity",
/** Tax number identification. */
TaxNumber = "taxNumber",
/** Medical card identification. */
MedicalCard = "medicalCard",
}

Loading

0 comments on commit b751396

Please sign in to comment.