forked from cory/tildefriends
		
	Compare commits
	
		
			14 Commits
		
	
	
		
			f0772f9b99
			...
			76d499f00b
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 76d499f00b | |||
| 46e711f0a5 | |||
| abffac3f82 | |||
| 27b275548e | |||
| 93ce253d1e | |||
| a5af312b39 | |||
| 4b5e8e8a43 | |||
| 443dd4d168 | |||
| 907479df84 | |||
| 9887a78e98 | |||
| f669371349 | |||
| 24c720c79a | |||
| 
						
						
							
						
						4485234980
	
				 | 
					
					
						|||
| 
						
						
							
						
						b6871c0b1f
	
				 | 
					
					
						
@@ -4,7 +4,8 @@
 | 
			
		||||
		<script>
 | 
			
		||||
			const g_data = $data;
 | 
			
		||||
		</script>
 | 
			
		||||
		<link rel="stylesheet" href="w3.css"></link>
 | 
			
		||||
		<link rel="stylesheet" href="w3.css" />
 | 
			
		||||
		<!-- prettier-ignore -->
 | 
			
		||||
		<style>
 | 
			
		||||
			/* 2018 Valiant Poppy */
 | 
			
		||||
			.w3-theme-l5 {color:#000 !important; background-color:#fbf3f3 !important}
 | 
			
		||||
 
 | 
			
		||||
@@ -42,10 +42,27 @@ window.addEventListener('load', function () {
 | 
			
		||||
		} else if (description.type === 'textarea') {
 | 
			
		||||
			return html`
 | 
			
		||||
				<li class="w3-row">
 | 
			
		||||
					<label class="w3-quarter" for=${'gs_' + key} style="font-weight: bold">${key}</label>
 | 
			
		||||
					<label class="w3-quarter" for=${'gs_' + key} style="font-weight: bold"
 | 
			
		||||
						>${key}</label
 | 
			
		||||
					>
 | 
			
		||||
					<div class="w3-rest w3-padding">${description.description}</div>
 | 
			
		||||
					<textarea class="w3-input" style="vertical-align: top; resize: vertical" id=${'gs_' + key}>${description.value}</textarea>
 | 
			
		||||
					<button class="w3-button w3-right w3-quarter w3-theme-action" @click=${(e) => global_settings_set(key, e.srcElement.previousElementSibling.value)}>Set</button>
 | 
			
		||||
					<textarea
 | 
			
		||||
						class="w3-input"
 | 
			
		||||
						style="vertical-align: top; resize: vertical"
 | 
			
		||||
						id=${'gs_' + key}
 | 
			
		||||
					>
 | 
			
		||||
${description.value}</textarea
 | 
			
		||||
					>
 | 
			
		||||
					<button
 | 
			
		||||
						class="w3-button w3-right w3-quarter w3-theme-action"
 | 
			
		||||
						@click=${(e) =>
 | 
			
		||||
							global_settings_set(
 | 
			
		||||
								key,
 | 
			
		||||
								e.srcElement.previousElementSibling.value
 | 
			
		||||
							)}
 | 
			
		||||
					>
 | 
			
		||||
						Set
 | 
			
		||||
					</button>
 | 
			
		||||
				</li>
 | 
			
		||||
			`;
 | 
			
		||||
		} else {
 | 
			
		||||
@@ -61,13 +78,17 @@ window.addEventListener('load', function () {
 | 
			
		||||
	}
 | 
			
		||||
	const user_template = (user, permissions) => html`
 | 
			
		||||
		<li class="w3-card w3-margin">
 | 
			
		||||
			<button class="w3-button w3-theme-action" @click=${(e) => delete_user(user)}>Delete</button>
 | 
			
		||||
			<button
 | 
			
		||||
				class="w3-button w3-theme-action"
 | 
			
		||||
				@click=${(e) => delete_user(user)}
 | 
			
		||||
			>
 | 
			
		||||
				Delete
 | 
			
		||||
			</button>
 | 
			
		||||
			${user}: ${permissions.map((x) => permission_template(x))}
 | 
			
		||||
		</li>
 | 
			
		||||
	`;
 | 
			
		||||
	const users_template = (users) =>
 | 
			
		||||
		html`
 | 
			
		||||
			<header class="w3-container w3-theme-l2"><h2>Users</h2></header>
 | 
			
		||||
		html` <header class="w3-container w3-theme-l2"><h2>Users</h2></header>
 | 
			
		||||
			<ul class="w3-ul">
 | 
			
		||||
				${Object.entries(users).map((u) => user_template(u[0], u[1]))}
 | 
			
		||||
			</ul>`;
 | 
			
		||||
 
 | 
			
		||||
@@ -118,7 +118,9 @@ async function main() {
 | 
			
		||||
			<ul class="w3-ul">` +
 | 
			
		||||
			ids
 | 
			
		||||
				.map(
 | 
			
		||||
						(id) => `<li style="overflow: hidden; text-wrap: nowrap; text-overflow: ellipsis">
 | 
			
		||||
					(
 | 
			
		||||
						id
 | 
			
		||||
					) => `<li style="overflow: hidden; text-wrap: nowrap; text-overflow: ellipsis">
 | 
			
		||||
				<button onclick="handler.export_id(event)" data-id="${id}" class="w3-button w3-theme">Export Identity</button>
 | 
			
		||||
				<button onclick="handler.delete_id(event)" data-id="${id}" class="w3-button w3-theme">Delete Identity</button>
 | 
			
		||||
				${id}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
{
 | 
			
		||||
	"type": "tildefriends-app",
 | 
			
		||||
	"emoji": "🐌",
 | 
			
		||||
	"previous": "&raSj7ozmSDNGmB6TtjDk7oOiTc33ZN+RrBMASJ2F4cA=.sha256"
 | 
			
		||||
	"previous": "&wA6sLaDxtYeFdVCCu8jyhPsGYtGZEjbWQHeGOn0Yifg=.sha256"
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -345,13 +345,15 @@ class TfElement extends LitElement {
 | 
			
		||||
					([k, v]) => html`
 | 
			
		||||
						<button
 | 
			
		||||
							title=${v}
 | 
			
		||||
							class="w3-bar-item w3-padding-large w3-hover-theme tab ${self.tab ==
 | 
			
		||||
							v
 | 
			
		||||
							class="w3-bar-item w3-padding w3-hover-theme tab ${self.tab == v
 | 
			
		||||
								? 'w3-theme-l2'
 | 
			
		||||
								: 'w3-theme-l1'}"
 | 
			
		||||
							@click=${() => self.set_tab(v)}
 | 
			
		||||
						>
 | 
			
		||||
							${k}
 | 
			
		||||
							<span class=${self.tab == v ? '' : 'w3-hide-small'}
 | 
			
		||||
								>${v.charAt(0).toUpperCase() + v.substring(1)}</span
 | 
			
		||||
							>
 | 
			
		||||
						</button>
 | 
			
		||||
					`
 | 
			
		||||
				)}
 | 
			
		||||
@@ -359,7 +361,9 @@ class TfElement extends LitElement {
 | 
			
		||||
		`;
 | 
			
		||||
		let contents = !this.loaded
 | 
			
		||||
			? this.loading
 | 
			
		||||
				? html`<div class="w3-panel w3-theme-l5 w3-card-4 w3-padding-large w3-round-xlarge">
 | 
			
		||||
				? html`<div
 | 
			
		||||
							class="w3-panel w3-theme-l5 w3-card-4 w3-padding-large w3-round-xlarge"
 | 
			
		||||
						>
 | 
			
		||||
							Loading...
 | 
			
		||||
						</div>
 | 
			
		||||
						${this.render_tab()}`
 | 
			
		||||
 
 | 
			
		||||
@@ -295,14 +295,18 @@ class TfComposeElement extends LitElement {
 | 
			
		||||
				{
 | 
			
		||||
					values: values,
 | 
			
		||||
					selectTemplate: function (item) {
 | 
			
		||||
						return item ? `[@${item.original.key}](${item.original.value})` : undefined;
 | 
			
		||||
						return item
 | 
			
		||||
							? `[@${item.original.key}](${item.original.value})`
 | 
			
		||||
							: undefined;
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
				{
 | 
			
		||||
					trigger: '&',
 | 
			
		||||
					values: this.autocomplete,
 | 
			
		||||
					selectTemplate: function (item) {
 | 
			
		||||
						return item ? `` : undefined;
 | 
			
		||||
						return item
 | 
			
		||||
							? ``
 | 
			
		||||
							: undefined;
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
			],
 | 
			
		||||
 
 | 
			
		||||
@@ -247,9 +247,7 @@ ${JSON.stringify(mention, null, 2)}</pre
 | 
			
		||||
		if (mentions.length) {
 | 
			
		||||
			let self = this;
 | 
			
		||||
			return html`
 | 
			
		||||
				<fieldset
 | 
			
		||||
					style="padding: 0.5em; border: 1px solid black"
 | 
			
		||||
				>
 | 
			
		||||
				<fieldset style="padding: 0.5em; border: 1px solid black">
 | 
			
		||||
					<legend>Mentions</legend>
 | 
			
		||||
					${mentions.map((x) => self.render_mention(x))}
 | 
			
		||||
				</fieldset>
 | 
			
		||||
 
 | 
			
		||||
@@ -105,6 +105,16 @@ class TfTabConnectionsElement extends LitElement {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	render_connection(connection) {
 | 
			
		||||
		let requests = Object.values(
 | 
			
		||||
			connection.requests.reduce(function (accumulator, value) {
 | 
			
		||||
				let key = `${value.name}:${Math.sign(value.request_number)}`;
 | 
			
		||||
				if (!accumulator[key]) {
 | 
			
		||||
					accumulator[key] = Object.assign({count: 0}, value);
 | 
			
		||||
				}
 | 
			
		||||
				accumulator[key].count++;
 | 
			
		||||
				return accumulator;
 | 
			
		||||
			}, {})
 | 
			
		||||
		);
 | 
			
		||||
		return html`
 | 
			
		||||
			<button
 | 
			
		||||
				class="w3-button w3-theme-d1"
 | 
			
		||||
@@ -116,9 +126,20 @@ class TfTabConnectionsElement extends LitElement {
 | 
			
		||||
			${connection.tunnel !== undefined
 | 
			
		||||
				? '🚇'
 | 
			
		||||
				: html`(${connection.host}:${connection.port})`}
 | 
			
		||||
			<div>${connection.requests.map(x => html`
 | 
			
		||||
				<span class="w3-tag w3-small">${x.request_number > 0 ? '🟩' : '🟥'} ${x.name}</span>
 | 
			
		||||
			`)}</div>
 | 
			
		||||
			<div>
 | 
			
		||||
				${requests.map(
 | 
			
		||||
					(x) => html`
 | 
			
		||||
						<span class="w3-tag w3-small"
 | 
			
		||||
							>${x.request_number > 0 ? '🟩' : '🟥'} ${x.name}
 | 
			
		||||
							<span
 | 
			
		||||
								class="w3-badge w3-white"
 | 
			
		||||
								style=${x.count > 1 ? undefined : 'display: none'}
 | 
			
		||||
								>${x.count}</span
 | 
			
		||||
							></span
 | 
			
		||||
						>
 | 
			
		||||
					`
 | 
			
		||||
				)}
 | 
			
		||||
			</div>
 | 
			
		||||
			<ul>
 | 
			
		||||
				${this.connections
 | 
			
		||||
					.filter((x) => x.tunnel === this.connections.indexOf(connection))
 | 
			
		||||
@@ -187,12 +208,16 @@ class TfTabConnectionsElement extends LitElement {
 | 
			
		||||
					${this.identities.map(
 | 
			
		||||
						(x) =>
 | 
			
		||||
							html`<li class="w3-bar">
 | 
			
		||||
								${x == this.server_identity ?
 | 
			
		||||
									html`<span class="w3-tag w3-medium w3-round w3-theme-l1">🖥 local server</span>` :
 | 
			
		||||
									undefined}
 | 
			
		||||
								${this.my_identities.indexOf(x) != -1 ?
 | 
			
		||||
									html`<span class="w3-tag w3-medium w3-round w3-theme-d1">😎 you</span>` :
 | 
			
		||||
									undefined}
 | 
			
		||||
								${x == this.server_identity
 | 
			
		||||
									? html`<span class="w3-tag w3-medium w3-round w3-theme-l1"
 | 
			
		||||
											>🖥 local server</span
 | 
			
		||||
										>`
 | 
			
		||||
									: undefined}
 | 
			
		||||
								${this.my_identities.indexOf(x) != -1
 | 
			
		||||
									? html`<span class="w3-tag w3-medium w3-round w3-theme-d1"
 | 
			
		||||
											>😎 you</span
 | 
			
		||||
										>`
 | 
			
		||||
									: undefined}
 | 
			
		||||
								<tf-user id=${x} .users=${this.users}></tf-user>
 | 
			
		||||
							</li>`
 | 
			
		||||
					)}
 | 
			
		||||
 
 | 
			
		||||
@@ -115,12 +115,16 @@ class TfTabNewsElement extends LitElement {
 | 
			
		||||
				></tf-profile>`
 | 
			
		||||
			: undefined;
 | 
			
		||||
		let edit_profile;
 | 
			
		||||
		if (!this.loading &&
 | 
			
		||||
		if (
 | 
			
		||||
			!this.loading &&
 | 
			
		||||
			this.users[this.whoami]?.name === undefined &&
 | 
			
		||||
			this.hash.substring(1) != this.whoami) {
 | 
			
		||||
			edit_profile = html`
 | 
			
		||||
				<div class="w3-panel w3-padding w3-round w3-card-4 w3-theme-l3">
 | 
			
		||||
					ℹ️ Follow your identity link ☝️ above to edit your profile and set your name.
 | 
			
		||||
			this.hash.substring(1) != this.whoami
 | 
			
		||||
		) {
 | 
			
		||||
			edit_profile = html` <div
 | 
			
		||||
				class="w3-panel w3-padding w3-round w3-card-4 w3-theme-l3"
 | 
			
		||||
			>
 | 
			
		||||
				ℹ️ Follow your identity link ☝️ above to edit your profile and set your
 | 
			
		||||
				name.
 | 
			
		||||
			</div>`;
 | 
			
		||||
		}
 | 
			
		||||
		return html`
 | 
			
		||||
 
 | 
			
		||||
@@ -19,6 +19,10 @@ class TfUserElement extends LitElement {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	render() {
 | 
			
		||||
		let image = html`<span
 | 
			
		||||
			class="w3-theme-light w3-circle"
 | 
			
		||||
			style="display: inline-block; width: 2em; height: 2em; text-align: center; line-height: 2em"
 | 
			
		||||
		>?</span>`;
 | 
			
		||||
		let name = this.users?.[this.id]?.name;
 | 
			
		||||
		name =
 | 
			
		||||
			name !== undefined
 | 
			
		||||
@@ -26,22 +30,21 @@ class TfUserElement extends LitElement {
 | 
			
		||||
				: html`<a target="_top" href=${'#' + this.id}>${this.id}</a>`;
 | 
			
		||||
 | 
			
		||||
		if (this.users[this.id]) {
 | 
			
		||||
			let image = this.users[this.id].image;
 | 
			
		||||
			image = typeof image == 'string' ? image : image?.link;
 | 
			
		||||
			return html` <div style="display: inline-block; font-weight: bold">
 | 
			
		||||
				<img
 | 
			
		||||
					style="width: 2em; height: 2em; vertical-align: middle; border-radius: 50%"
 | 
			
		||||
					?hidden=${image === undefined}
 | 
			
		||||
					src="${image ? '/' + image + '/view' : undefined}"
 | 
			
		||||
				/>
 | 
			
		||||
				${name}
 | 
			
		||||
			</div>`;
 | 
			
		||||
		} else {
 | 
			
		||||
			return html` <div style="display: inline-block; font-weight: bold">
 | 
			
		||||
				${name}
 | 
			
		||||
			</div>`;
 | 
			
		||||
			let image_link = this.users[this.id].image;
 | 
			
		||||
			image_link = typeof image_link == 'string' ? image_link : image_link?.link;
 | 
			
		||||
			if (image_link !== undefined) {
 | 
			
		||||
				image = html`<img
 | 
			
		||||
					class="w3-circle"
 | 
			
		||||
					style="width: 2em; height: 2em; vertical-align: middle"
 | 
			
		||||
					src="/${image_link}/view"
 | 
			
		||||
				/>`;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return html` <div style="display: inline-block; font-weight: bold">
 | 
			
		||||
			${image}
 | 
			
		||||
			${name}
 | 
			
		||||
		</div>`;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
customElements.define('tf-user', TfUserElement);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										23
									
								
								src/ssb.db.c
									
									
									
									
									
								
							
							
						
						
									
										23
									
								
								src/ssb.db.c
									
									
									
									
									
								
							@@ -737,12 +737,11 @@ bool tf_ssb_db_blob_store(tf_ssb_t* ssb, const uint8_t* blob, size_t size, char*
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool tf_ssb_db_get_message_by_author_and_sequence(tf_ssb_t* ssb, const char* author, int64_t sequence, char* out_message_id, size_t out_message_id_size, char* out_previous,
 | 
			
		||||
	size_t out_previous_size, char* out_author, size_t out_author_size, double* out_timestamp, char** out_content, char* out_hash, size_t out_hash_size, char* out_signature,
 | 
			
		||||
	size_t out_signature_size, int* out_flags)
 | 
			
		||||
	size_t out_previous_size, double* out_timestamp, char** out_content, char* out_hash, size_t out_hash_size, char* out_signature, size_t out_signature_size, int* out_flags)
 | 
			
		||||
{
 | 
			
		||||
	bool found = false;
 | 
			
		||||
	sqlite3_stmt* statement;
 | 
			
		||||
	const char* query = "SELECT id, previous, author, timestamp, json(content), hash, signature, flags FROM messages WHERE author = ?1 AND sequence = ?2";
 | 
			
		||||
	const char* query = "SELECT id, previous, timestamp, json(content), hash, signature, flags FROM messages WHERE author = ?1 AND sequence = ?2";
 | 
			
		||||
	sqlite3* db = tf_ssb_acquire_db_reader(ssb);
 | 
			
		||||
	if (sqlite3_prepare(db, query, -1, &statement, NULL) == SQLITE_OK)
 | 
			
		||||
	{
 | 
			
		||||
@@ -766,29 +765,25 @@ bool tf_ssb_db_get_message_by_author_and_sequence(tf_ssb_t* ssb, const char* aut
 | 
			
		||||
					snprintf(out_previous, out_previous_size, "%s", (const char*)sqlite3_column_text(statement, 1));
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			if (out_author)
 | 
			
		||||
			{
 | 
			
		||||
				snprintf(out_author, out_author_size, "%s", (const char*)sqlite3_column_text(statement, 2));
 | 
			
		||||
			}
 | 
			
		||||
			if (out_timestamp)
 | 
			
		||||
			{
 | 
			
		||||
				*out_timestamp = sqlite3_column_double(statement, 3);
 | 
			
		||||
				*out_timestamp = sqlite3_column_double(statement, 2);
 | 
			
		||||
			}
 | 
			
		||||
			if (out_content)
 | 
			
		||||
			{
 | 
			
		||||
				*out_content = tf_strdup((const char*)sqlite3_column_text(statement, 4));
 | 
			
		||||
				*out_content = tf_strdup((const char*)sqlite3_column_text(statement, 3));
 | 
			
		||||
			}
 | 
			
		||||
			if (out_hash)
 | 
			
		||||
			{
 | 
			
		||||
				snprintf(out_hash, out_hash_size, "%s", (const char*)sqlite3_column_text(statement, 5));
 | 
			
		||||
				snprintf(out_hash, out_hash_size, "%s", (const char*)sqlite3_column_text(statement, 4));
 | 
			
		||||
			}
 | 
			
		||||
			if (out_signature)
 | 
			
		||||
			{
 | 
			
		||||
				snprintf(out_signature, out_signature_size, "%s", (const char*)sqlite3_column_text(statement, 6));
 | 
			
		||||
				snprintf(out_signature, out_signature_size, "%s", (const char*)sqlite3_column_text(statement, 5));
 | 
			
		||||
			}
 | 
			
		||||
			if (out_flags)
 | 
			
		||||
			{
 | 
			
		||||
				*out_flags = sqlite3_column_int(statement, 7);
 | 
			
		||||
				*out_flags = sqlite3_column_int(statement, 6);
 | 
			
		||||
			}
 | 
			
		||||
			found = true;
 | 
			
		||||
		}
 | 
			
		||||
@@ -1834,8 +1829,8 @@ bool tf_ssb_db_verify(tf_ssb_t* ssb, const char* id)
 | 
			
		||||
			char hash[32];
 | 
			
		||||
			char signature[256];
 | 
			
		||||
			int flags = 0;
 | 
			
		||||
			if (tf_ssb_db_get_message_by_author_and_sequence(ssb, id, i, message_id, sizeof(message_id), previous, sizeof(previous), NULL, 0, ×tamp, &content, hash,
 | 
			
		||||
					sizeof(hash), signature, sizeof(signature), &flags))
 | 
			
		||||
			if (tf_ssb_db_get_message_by_author_and_sequence(
 | 
			
		||||
					ssb, id, i, message_id, sizeof(message_id), previous, sizeof(previous), ×tamp, &content, hash, sizeof(hash), signature, sizeof(signature), &flags))
 | 
			
		||||
			{
 | 
			
		||||
				JSValue message = tf_ssb_format_message(context, previous, id, i, timestamp, hash, content, signature, flags);
 | 
			
		||||
				char calculated_id[k_id_base64_len];
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										16
									
								
								src/ssb.db.h
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								src/ssb.db.h
									
									
									
									
									
								
							@@ -122,13 +122,19 @@ JSValue tf_ssb_db_get_message_by_id(tf_ssb_t* ssb, const char* id, bool is_keys)
 | 
			
		||||
** @param sequence The message sequence number.
 | 
			
		||||
** @param[out] out_message_id Populated with the message identifier.
 | 
			
		||||
** @param out_message_id_size The size of the out_message_id buffer.
 | 
			
		||||
** @param[out] out_previous Populated with the previous message identifier.
 | 
			
		||||
** @param out_previous_size The size of the out_previous buffer.
 | 
			
		||||
** @param[out] out_timestamp Populated with the timestamp.
 | 
			
		||||
** @param[out] out_content Populated with the message content.  Free with tf_free().
 | 
			
		||||
** @param[out] out_hash Populated with the message hash format.
 | 
			
		||||
** @param out_hash_size The size of the out_hash buffer.
 | 
			
		||||
** @param[out] out_signature Populated with the message signature.
 | 
			
		||||
** @param out_signature_size The size of the out_signature buffer.
 | 
			
		||||
** @param[out] out_flags Populated with flags describing the format of the message.
 | 
			
		||||
** @return True if the message was found and retrieved.
 | 
			
		||||
*/
 | 
			
		||||
bool tf_ssb_db_get_message_by_author_and_sequence(tf_ssb_t* ssb, const char* author, int64_t sequence, char* out_message_id, size_t out_message_id_size, char* out_previous,
 | 
			
		||||
	size_t out_previous_size, char* out_author, size_t out_author_size, double* out_timestamp, char** out_content, char* out_hash, size_t out_hash_size, char* out_signature,
 | 
			
		||||
	size_t out_signature_size, int* out_flags);
 | 
			
		||||
	size_t out_previous_size, double* out_timestamp, char** out_content, char* out_hash, size_t out_hash_size, char* out_signature, size_t out_signature_size, int* out_flags);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
** Get information about the last message from an author.
 | 
			
		||||
@@ -380,6 +386,12 @@ bool tf_ssb_db_set_property(tf_ssb_t* ssb, const char* id, const char* key, cons
 | 
			
		||||
*/
 | 
			
		||||
void tf_ssb_db_resolve_index_async(tf_ssb_t* ssb, const char* host, void (*callback)(const char* path, void* user_data), void* user_data);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
** Verify an author's feed.
 | 
			
		||||
** @param ssb The SSB instance.
 | 
			
		||||
** @param id The author'd identity.
 | 
			
		||||
** @return true If the feed verified successfully.
 | 
			
		||||
*/
 | 
			
		||||
bool tf_ssb_db_verify(tf_ssb_t* ssb, const char* id);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user