mirror of
https://github.com/chatmail/core.git
synced 2026-04-06 07:32:12 +03:00
* integrate json-rpc repo https://github.com/deltachat/deltachat-jsonrpc * get target dir from cargo * fix clippy * use node 16 in ci use `npm i` instead of `npm ci` try fix ci script and fix a doc comment * fix get_provider_info docs * refactor function name * fix formatting make test pass fix clippy * update .gitignore * change now returns event names as id directly, no conversion method or number ids anymore also longer timeout for requesting test accounts from mailadm * fix compile after rebase * add json api to cffi and expose it in dc node * add some files to npm ignore that don't need to be in the npm package * add jsonrpc crate to set_core_version * add jsonrpc feature flag * call a jsonrpc function in segfault example * break loop on empty response * fix closing segfault thanks again to link2xt for figguring this out * activate other tests again * remove selectAccount from highlevel client * put jsonrpc stuff in own module * disable jsonrpc by default * add @deltachat/jsonrpc-client to make sure its dependencies are installed, too whwn installing dc-node * commit types.ts that dc-node has everything it needs to provide @deltachat/jsonrpc-client without an extra ts compile step * improve naming * Changes for tokio compat, upgrade to yerpc 0.3 This also changes the webserver binary to use axum in place of tide. * Improvements to typescript package * Improve docs. * improve docs, fix example * Fix CFFI for JSON-RPC changes * use stable toolchain not 1.56.0 * fix ci * try to fix ci * remove emtpy file allow unused code for new_from_arc * expose anyhow errors feature name was wrong * use multi-threaded runtime in JSON-RPC webserver * improve test setup and code style * don't wait for IO on webserver start * Bump yerpc to 0.3.1 with fix for axum server * update todo document remove specific api stuff for now, we now have the an incremental aproach on moving not the all at-once effort I though it would be * remove debug logs * changelog entry about the jsonrpc * Fix method name casings and cleanups * Improve JSON-RPC CI, no need to build things multiple times * Naming consistency: Use DeltaChat not Deltachat * Improve documentation * fix docs * adress dig's comments - description in cargo.toml - impl From<EventType> for EventTypeName - rename `CommandApi::new_from_arc` -> `CommandApi::from_arc` - pre-allocate if we know the entry count already - remove unused enumerate - remove unused serde attribute comment - rename `FullChat::from_dc_chat_id` -> `FullChat::try_from_dc_chat_id` * make it more idiomatic: rename `ContactObject::from_dc_contact -> `ContactObject::try_from_dc_contact` * apply link2xt's suggestions: - unref jsonrpc_instance in same thread it was created in - increase `max_queue_size` from 1 to 1000 * reintroduce segfault test script * remove unneeded context thanks to link2xt for pointing that out * Update deltachat-ffi/deltachat.h Co-authored-by: bjoern <r10s@b44t.com> * Update deltachat-ffi/deltachat.h Co-authored-by: bjoern <r10s@b44t.com> * make sure to use dc_str_unref instead of free on cstrings returned/owned by rust * Increase online test timeouts for CI * fix the typos thanks to ralphtheninja for finding them * restore same configure behaviour as desktop: make configure restart io with the old configuration if it had one on error * found another segfault: this time in batch_set_config * remove print from test * make dcn_json_rpc_request return undefined instead of not returning this might have been the cause for the second segfault * add set_config_from_qr to jsonrpc * add `add_device_message` to jsonrpc * jsonrpc: add `get_fresh_msgs` and `get_fresh_msg_cnt` * jsonrpc: add dm_chat_contact to ChatListItemFetchResult * add webxdc methods to jsonrpc: - `webxdc_send_status_update` - `webxdc_get_status_updates` - `message_get_webxdc_info` * add `chat_get_media` to jsonrpc also add viewtype wrapper enum and use it in `MessageObject`, additionally to using it in `chat_get_media` * use camelCase in all js object properties * Add check_qr function to jsonrpc * Fixed clippy errors and formatting * Fixed formatting * fix changelog ordering after rebase * fix compile after merging in master branch Co-authored-by: Simon Laux <mobile.info@simonlaux.de> Co-authored-by: Simon Laux <Simon-Laux@users.noreply.github.com> Co-authored-by: bjoern <r10s@b44t.com> Co-authored-by: flipsimon <28535045+flipsimon@users.noreply.github.com>
232 lines
5.9 KiB
TypeScript
232 lines
5.9 KiB
TypeScript
/* eslint-disable camelcase */
|
|
|
|
import binding from './binding'
|
|
import { EventId2EventName } from './constants'
|
|
import { EventEmitter } from 'events'
|
|
import { existsSync } from 'fs'
|
|
import rawDebug from 'debug'
|
|
import { tmpdir } from 'os'
|
|
import { join } from 'path'
|
|
import { Context } from './context'
|
|
const debug = rawDebug('deltachat:node:index')
|
|
|
|
const noop = function () {}
|
|
interface NativeAccount {}
|
|
|
|
/**
|
|
* Wrapper around dcn_account_t*
|
|
*/
|
|
export class AccountManager extends EventEmitter {
|
|
dcn_accounts: NativeAccount
|
|
accountDir: string
|
|
jsonRpcStarted = false
|
|
|
|
constructor(cwd: string, os = 'deltachat-node') {
|
|
super()
|
|
debug('DeltaChat constructor')
|
|
|
|
this.accountDir = cwd
|
|
this.dcn_accounts = binding.dcn_accounts_new(os, this.accountDir)
|
|
}
|
|
|
|
getAllAccountIds() {
|
|
return binding.dcn_accounts_get_all(this.dcn_accounts)
|
|
}
|
|
|
|
selectAccount(account_id: number) {
|
|
return binding.dcn_accounts_select_account(this.dcn_accounts, account_id)
|
|
}
|
|
|
|
selectedAccount(): number {
|
|
return binding.dcn_accounts_get_selected_account(this.dcn_accounts)
|
|
}
|
|
|
|
addAccount(): number {
|
|
return binding.dcn_accounts_add_account(this.dcn_accounts)
|
|
}
|
|
|
|
addClosedAccount(): number {
|
|
return binding.dcn_accounts_add_closed_account(this.dcn_accounts)
|
|
}
|
|
|
|
removeAccount(account_id: number) {
|
|
return binding.dcn_accounts_remove_account(this.dcn_accounts, account_id)
|
|
}
|
|
|
|
accountContext(account_id: number) {
|
|
const native_context = binding.dcn_accounts_get_account(
|
|
this.dcn_accounts,
|
|
account_id
|
|
)
|
|
if (native_context === null) {
|
|
throw new Error(
|
|
`could not get context with id ${account_id}, does it even exist? please check your ids`
|
|
)
|
|
}
|
|
return new Context(this, native_context, account_id)
|
|
}
|
|
|
|
migrateAccount(dbfile: string): number {
|
|
return binding.dcn_accounts_migrate_account(this.dcn_accounts, dbfile)
|
|
}
|
|
|
|
close() {
|
|
this.stopIO()
|
|
debug('unrefing context')
|
|
binding.dcn_accounts_unref(this.dcn_accounts)
|
|
debug('Unref end')
|
|
}
|
|
|
|
emit(
|
|
event: string | symbol,
|
|
account_id: number,
|
|
data1: any,
|
|
data2: any
|
|
): boolean {
|
|
super.emit('ALL', event, account_id, data1, data2)
|
|
return super.emit(event, account_id, data1, data2)
|
|
}
|
|
|
|
handleCoreEvent(
|
|
eventId: number,
|
|
accountId: number,
|
|
data1: number,
|
|
data2: number | string
|
|
) {
|
|
const eventString = EventId2EventName[eventId]
|
|
debug('event', eventString, accountId, data1, data2)
|
|
debug(eventString, data1, data2)
|
|
if (!this.emit) {
|
|
console.log('Received an event but EventEmitter is already destroyed.')
|
|
console.log(eventString, data1, data2)
|
|
return
|
|
}
|
|
this.emit(eventString, accountId, data1, data2)
|
|
}
|
|
|
|
startEvents() {
|
|
if (this.dcn_accounts === null) {
|
|
throw new Error('dcn_account is null')
|
|
}
|
|
binding.dcn_accounts_start_event_handler(
|
|
this.dcn_accounts,
|
|
this.handleCoreEvent.bind(this)
|
|
)
|
|
debug('Started event handler')
|
|
}
|
|
|
|
startJsonRpcHandler(callback: ((response: string) => void) | null) {
|
|
if (this.dcn_accounts === null) {
|
|
throw new Error('dcn_account is null')
|
|
}
|
|
if (!callback) {
|
|
throw new Error('no callback set')
|
|
}
|
|
if (this.jsonRpcStarted) {
|
|
throw new Error('jsonrpc was started already')
|
|
}
|
|
|
|
binding.dcn_accounts_start_jsonrpc(this.dcn_accounts, callback.bind(this))
|
|
debug('Started JSON-RPC handler')
|
|
this.jsonRpcStarted = true
|
|
}
|
|
|
|
jsonRpcRequest(message: string) {
|
|
if (!this.jsonRpcStarted) {
|
|
throw new Error(
|
|
'jsonrpc is not active, start it with startJsonRpcHandler first'
|
|
)
|
|
}
|
|
binding.dcn_json_rpc_request(this.dcn_accounts, message)
|
|
}
|
|
|
|
startIO() {
|
|
binding.dcn_accounts_start_io(this.dcn_accounts)
|
|
}
|
|
|
|
stopIO() {
|
|
binding.dcn_accounts_stop_io(this.dcn_accounts)
|
|
}
|
|
|
|
static maybeValidAddr(addr: string) {
|
|
debug('DeltaChat.maybeValidAddr')
|
|
if (addr === null) return false
|
|
return Boolean(binding.dcn_maybe_valid_addr(addr))
|
|
}
|
|
|
|
static parseGetInfo(info: string) {
|
|
debug('static _getInfo')
|
|
const result: { [key: string]: string } = {}
|
|
|
|
const regex = /^(\w+)=(.*)$/i
|
|
info
|
|
.split('\n')
|
|
.filter(Boolean)
|
|
.forEach((line) => {
|
|
const match = regex.exec(line)
|
|
if (match) {
|
|
result[match[1]] = match[2]
|
|
}
|
|
})
|
|
|
|
return result
|
|
}
|
|
|
|
static newTemporary() {
|
|
let directory = null
|
|
while (true) {
|
|
const randomString = Math.random().toString(36).substr(2, 5)
|
|
directory = join(tmpdir(), 'deltachat-' + randomString)
|
|
if (!existsSync(directory)) break
|
|
}
|
|
const dc = new AccountManager(directory)
|
|
const accountId = dc.addAccount()
|
|
const context = dc.accountContext(accountId)
|
|
return { dc, context, accountId, directory }
|
|
}
|
|
|
|
static getSystemInfo() {
|
|
debug('DeltaChat.getSystemInfo')
|
|
const { dc, context } = AccountManager.newTemporary()
|
|
const info = AccountManager.parseGetInfo(
|
|
binding.dcn_get_info(context.dcn_context)
|
|
)
|
|
const {
|
|
deltachat_core_version,
|
|
sqlite_version,
|
|
sqlite_thread_safe,
|
|
libetpan_version,
|
|
openssl_version,
|
|
compile_date,
|
|
arch,
|
|
} = info
|
|
const result = {
|
|
deltachat_core_version,
|
|
sqlite_version,
|
|
sqlite_thread_safe,
|
|
libetpan_version,
|
|
openssl_version,
|
|
compile_date,
|
|
arch,
|
|
}
|
|
context.unref()
|
|
dc.close()
|
|
return result
|
|
}
|
|
|
|
/** get information about the provider
|
|
*
|
|
* This function creates a temporary context to be standalone,
|
|
* if posible use `Context.getProviderFromEmail` instead. (otherwise potential proxy settings are not used)
|
|
* @deprecated
|
|
*/
|
|
static getProviderFromEmail(email: string) {
|
|
debug('DeltaChat.getProviderFromEmail')
|
|
const { dc, context } = AccountManager.newTemporary()
|
|
const provider = context.getProviderFromEmail(email)
|
|
context.unref()
|
|
dc.close()
|
|
return provider
|
|
}
|
|
}
|