2024-03-16 08:40:24 +00:00
export interface User {
id : string ;
email : string ;
hashed_password : string ;
subscription : {
external : Record < never , never > ;
expires_at : string ;
updated_at : string ;
} ;
status : 'trial' | 'active' | 'inactive' ;
extra : {
is_email_verified : boolean ;
is_admin? : boolean ;
dav_hashed_password? : string ;
2025-02-26 17:43:53 +00:00
expenses_currency? : SupportedCurrencySymbol ;
2025-05-29 16:30:28 +00:00
multi_factor_auth_methods? : MultiFactorAuthMethod [ ] ;
2024-03-16 08:40:24 +00:00
} ;
created_at : Date ;
}
export interface UserSession {
id : string ;
user_id : string ;
expires_at : Date ;
last_seen_at : Date ;
created_at : Date ;
}
export interface FreshContextState {
user? : User ;
session? : UserSession ;
}
export interface VerificationCode {
id : string ;
user_id : string ;
code : string ;
verification : {
type : 'email' ;
id : string ;
} ;
expires_at : Date ;
created_at : Date ;
}
export interface DashboardLink {
url : string ;
name : string ;
}
export interface Dashboard {
id : string ;
user_id : string ;
data : {
links : DashboardLink [ ] ;
notes : string ;
} ;
created_at : Date ;
}
export type NewsFeedType = 'rss' | 'atom' | 'json' ;
export type NewsFeedCrawlType = 'direct' | 'googlebot' | 'proxy' ;
export interface NewsFeed {
id : string ;
user_id : string ;
feed_url : string ;
last_crawled_at : Date | null ;
extra : {
title? : string ;
feed_type? : NewsFeedType ;
crawl_type? : NewsFeedCrawlType ;
} ;
created_at : Date ;
}
export interface NewsFeedArticle {
id : string ;
user_id : string ;
feed_id : string ;
article_url : string ;
article_title : string ;
article_summary : string ;
article_date : Date ;
is_read : boolean ;
2025-02-26 17:43:53 +00:00
extra : Record < never , never > ; // NOTE: Here for potential future fields
2024-03-16 08:40:24 +00:00
created_at : Date ;
}
2024-04-03 13:02:04 +00:00
export interface Directory {
2024-04-04 16:55:47 +00:00
user_id : string ;
2024-04-03 13:02:04 +00:00
parent_path : string ;
directory_name : string ;
has_write_access : boolean ;
size_in_bytes : number ;
2024-03-17 11:43:58 +00:00
updated_at : Date ;
created_at : Date ;
}
2024-03-17 17:00:05 +00:00
2024-04-03 13:02:04 +00:00
export interface DirectoryFile {
2024-04-04 16:55:47 +00:00
user_id : string ;
2024-04-03 13:02:04 +00:00
parent_path : string ;
file_name : string ;
has_write_access : boolean ;
size_in_bytes : number ;
updated_at : Date ;
created_at : Date ;
2024-03-18 19:18:29 +00:00
}
2025-02-26 17:43:53 +00:00
export interface Budget {
id : string ;
user_id : string ;
name : string ;
month : string ;
value : number ;
extra : {
usedValue : number ;
availableValue : number ;
} ;
created_at : Date ;
}
export interface Expense {
id : string ;
user_id : string ;
cost : number ;
description : string ;
budget : string ;
date : string ;
is_recurring : boolean ;
extra : Record < never , never > ; // NOTE: Here for potential future fields
created_at : Date ;
}
export type SupportedCurrencySymbol = '$' | '€' | '£' | '¥' | '₹' ;
type SupportedCurrency = 'USD' | 'EUR' | 'GBP' | 'JPY' | 'INR' ;
export const currencyMap = new Map < SupportedCurrencySymbol , SupportedCurrency > ( [
[ '$' , 'USD' ] ,
[ '€' , 'EUR' ] ,
[ '£' , 'GBP' ] ,
[ '¥' , 'JPY' ] ,
[ '₹' , 'INR' ] ,
] ) ;
2025-05-25 14:48:53 +00:00
export type PartialDeep < T > = ( T extends ( infer U ) [ ] ? PartialDeep < U > [ ] : { [ P in keyof T ] ? : PartialDeep < T [ P ] > } ) | T ;
export type OptionalApp = 'news' | 'notes' | 'photos' | 'expenses' ;
export interface Config {
auth : {
/** The base URL of the application you use to access the app, i.e. "http://localhost:8000" or "https://cloud.example.com" */
baseUrl : string ;
/** If true, anyone can sign up for an account. Note that it's always possible to sign up for the first user, and they will be an admin */
allowSignups : boolean ;
/** If true, email verification will be required for signups (using Brevo) */
enableEmailVerification : boolean ;
/** If true, all signups become active for 100 years */
enableForeverSignup : boolean ;
2025-05-29 16:30:28 +00:00
/** If true, users can enable multi-factor authentication (TOTP or Passkeys) */
enableMultiFactor : boolean ;
2025-05-25 14:48:53 +00:00
/** Can be set to allow more than the baseUrl's domain for session cookies */
allowedCookieDomains : string [ ] ;
/** If true, the cookie domain will not be strictly set and checked against. This skipping slightly reduces security, but is usually necessary for reverse proxies like Cloudflare Tunnel. */
skipCookieDomainSecurity : boolean ;
2025-06-05 17:10:40 +00:00
/** If true, single sign-on will be enabled */
enableSingleSignOn : boolean ;
/** The Discovery URL (AKA Issuer) of the identity/single sign-on provider */
singleSignOnUrl : string ;
/** The attribute to prefer as email of the identity/single sign-on provider */
singleSignOnEmailAttribute : string ;
/** The scopes to request from the identity/single sign-on provider */
singleSignOnScopes : string [ ] ;
2025-05-25 14:48:53 +00:00
} ;
files : {
/** The root-relative root path for files, i.e. "data-files" */
rootPath : string ;
} ;
core : {
/** dashboard and files cannot be disabled */
enabledApps : OptionalApp [ ] ;
} ;
visuals : {
/** An override title of the application. Empty shows the default title. */
title : string ;
/** An override description of the application. Empty shows the default description. */
description : string ;
/** The email address to contact for help. Empty will disable/hide the "need help" sections. */
helpEmail : string ;
} ;
}
2025-05-29 16:30:28 +00:00
export type MultiFactorAuthMethodType = 'totp' | 'passkey' ;
export interface MultiFactorAuthMethod {
type : MultiFactorAuthMethodType ;
id : string ;
name : string ;
enabled : boolean ;
created_at : Date ;
metadata : {
totp ? : {
hashed_secret : string ;
hashed_backup_codes : string [ ] ;
} ;
passkey ? : {
credential_id : string ;
public_key : string ;
counter? : number ;
device_type? : string ;
backed_up? : boolean ;
transports? : AuthenticatorTransport [ ] ;
} ;
} ;
}