mirror of
https://github.com/AsamK/signal-cli.git
synced 2026-01-26 18:53:34 +00:00
Compare commits
13 Commits
3af9dff0ed
...
14297986f2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
14297986f2 | ||
|
|
0bd4d554d8 | ||
|
|
32c8d4f801 | ||
|
|
82abc20871 | ||
|
|
e8ab01f665 | ||
|
|
dee557a9ad | ||
|
|
f1fa2eba1d | ||
|
|
ccd58bbf23 | ||
|
|
54700d9cd0 | ||
|
|
984ea47f9d | ||
|
|
9458972d15 | ||
|
|
8eb9662694 | ||
|
|
a9be1aa608 |
6
.github/workflows/ci.yml
vendored
6
.github/workflows/ci.yml
vendored
@ -16,7 +16,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
java: [ '21', '25' ]
|
||||
java: [ '25' ]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
@ -58,8 +58,8 @@ jobs:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: graalvm/setup-graalvm@v1
|
||||
with:
|
||||
version: 'latest'
|
||||
java-version: '21'
|
||||
distribution: 'graalvm'
|
||||
java-version: '25'
|
||||
cache: 'gradle'
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Build with Gradle
|
||||
|
||||
2
.github/workflows/codeql-analysis.yml
vendored
2
.github/workflows/codeql-analysis.yml
vendored
@ -24,7 +24,7 @@ jobs:
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
distribution: 'zulu'
|
||||
java-version: 21
|
||||
java-version: 25
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
25
CHANGELOG.md
25
CHANGELOG.md
@ -2,6 +2,31 @@
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
**Attention**: Now requires Java 25
|
||||
|
||||
### Breaking changes
|
||||
|
||||
- Remove isRegistered method without parameters from Signal dbus interface, which always returned `true`
|
||||
- Remove `sandbox` value for --service-environment parameter, use `staging` instead
|
||||
- The `daemon` command now requires at least one channel parameter (`--socket`, `--dbus`, ...) and no longer defaults to dbus
|
||||
|
||||
## [0.13.23] - 2026-01-24
|
||||
|
||||
Requires libsignal-client version 0.86.12.
|
||||
|
||||
### Added
|
||||
|
||||
- Add sendPollCreate, sendPollVote, sendPollTerminate commands for polls
|
||||
- Add updateDevice command to set device name of linked devices
|
||||
|
||||
### Changed
|
||||
|
||||
- Allow updating contact names from linked devices
|
||||
|
||||
### Fixed
|
||||
|
||||
- Start multi account mode even if some accounts have authorization failures
|
||||
|
||||
## [0.13.22] - 2025-11-14
|
||||
|
||||
Requires libsignal-client version 0.86.1.
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
FROM docker.io/azul/zulu-openjdk:21-jre-headless
|
||||
FROM docker.io/azul/zulu-openjdk:25-jre-headless
|
||||
|
||||
LABEL org.opencontainers.image.source=https://github.com/AsamK/signal-cli
|
||||
LABEL org.opencontainers.image.description="signal-cli provides an unofficial commandline, dbus and JSON-RPC interface for the Signal messenger."
|
||||
|
||||
@ -8,7 +8,7 @@ For registering you need a phone number where you can receive SMS or incoming ca
|
||||
|
||||
signal-cli is primarily intended to be used on servers to notify admins of important events.
|
||||
For this use-case, it has a daemon mode with JSON-RPC interface ([man page](https://github.com/AsamK/signal-cli/blob/master/man/signal-cli-jsonrpc.5.adoc))
|
||||
and D-BUS interface ([man page](https://github.com/AsamK/signal-cli/blob/master/man/signal-cli-dbus.5.adoc)) .
|
||||
and D-BUS interface ([man page](https://github.com/AsamK/signal-cli/blob/master/man/signal-cli-dbus.5.adoc)).
|
||||
For the JSON-RPC interface there's also a simple [example client](https://github.com/AsamK/signal-cli/tree/master/client), written in Rust.
|
||||
|
||||
signal-cli needs to be kept up-to-date to keep up with Signal-Server changes.
|
||||
@ -23,7 +23,7 @@ Windows. There's also a [docker image and some Linux packages](https://github.co
|
||||
|
||||
System requirements:
|
||||
|
||||
- at least Java Runtime Environment (JRE) 21
|
||||
- at least Java Runtime Environment (JRE) 25
|
||||
- native library: libsignal-client
|
||||
|
||||
The native libs are bundled for x86_64 Linux (with recent enough glibc), Windows and MacOS. For other
|
||||
|
||||
@ -3,17 +3,17 @@ plugins {
|
||||
application
|
||||
eclipse
|
||||
`check-lib-versions`
|
||||
id("org.graalvm.buildtools.native") version "0.11.3"
|
||||
id("org.graalvm.buildtools.native") version "0.11.4"
|
||||
}
|
||||
|
||||
allprojects {
|
||||
group = "org.asamk"
|
||||
version = "0.13.23-SNAPSHOT"
|
||||
version = "0.14.0-SNAPSHOT"
|
||||
}
|
||||
|
||||
java {
|
||||
sourceCompatibility = JavaVersion.VERSION_21
|
||||
targetCompatibility = JavaVersion.VERSION_21
|
||||
sourceCompatibility = JavaVersion.VERSION_25
|
||||
targetCompatibility = JavaVersion.VERSION_25
|
||||
|
||||
if (!JavaVersion.current().isCompatibleWith(targetCompatibility)) {
|
||||
toolchain {
|
||||
@ -39,7 +39,7 @@ graalvmNative {
|
||||
if (System.getenv("GRAALVM_HOME") == null) {
|
||||
toolchainDetection.set(true)
|
||||
javaLauncher.set(javaToolchains.launcherFor {
|
||||
languageVersion.set(JavaLanguageVersion.of(21))
|
||||
languageVersion.set(JavaLanguageVersion.of(25))
|
||||
})
|
||||
} else {
|
||||
toolchainDetection.set(false)
|
||||
|
||||
@ -7,11 +7,11 @@ plugins {
|
||||
}
|
||||
|
||||
tasks.named<KotlinCompilationTask<KotlinJvmCompilerOptions>>("compileKotlin").configure {
|
||||
compilerOptions.jvmTarget.set(JvmTarget.JVM_17)
|
||||
compilerOptions.jvmTarget.set(JvmTarget.JVM_24)
|
||||
}
|
||||
|
||||
java {
|
||||
targetCompatibility = JavaVersion.VERSION_17
|
||||
targetCompatibility = JavaVersion.VERSION_24
|
||||
}
|
||||
|
||||
repositories {
|
||||
|
||||
@ -1,5 +1,3 @@
|
||||
@file:Suppress("DEPRECATION")
|
||||
|
||||
import org.gradle.api.Plugin
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.Task
|
||||
@ -8,7 +6,7 @@ import javax.xml.parsers.DocumentBuilderFactory
|
||||
|
||||
class CheckLibVersionsPlugin : Plugin<Project> {
|
||||
override fun apply(project: Project) {
|
||||
project.task("checkLibVersions") {
|
||||
project.tasks.register("checkLibVersions") {
|
||||
description =
|
||||
"Find any 3rd party libraries which have released new versions to the central Maven repo since we last upgraded."
|
||||
doLast {
|
||||
@ -28,7 +26,7 @@ class CheckLibVersionsPlugin : Plugin<Project> {
|
||||
try {
|
||||
val dbf = DocumentBuilderFactory.newInstance()
|
||||
val db = dbf.newDocumentBuilder()
|
||||
val doc = db.parse(metaDataUrl);
|
||||
val doc = db.parse(metaDataUrl)
|
||||
val newest = doc.getElementsByTagName("latest").item(0).textContent
|
||||
if (version != newest.toString()) {
|
||||
println("UPGRADE {\"group\": \"$group\", \"name\": \"$name\", \"current\": \"$version\", \"latest\": \"$newest\"}")
|
||||
|
||||
@ -45,6 +45,9 @@
|
||||
<content_attribute id="social-chat">intense</content_attribute>
|
||||
</content_rating>
|
||||
<releases>
|
||||
<release version="0.13.23" date="2026-01-24">
|
||||
<url type="details">https://github.com/AsamK/signal-cli/releases/tag/v0.13.23</url>
|
||||
</release>
|
||||
<release version="0.13.22" date="2025-11-14">
|
||||
<url type="details">https://github.com/AsamK/signal-cli/releases/tag/v0.13.22</url>
|
||||
</release>
|
||||
|
||||
@ -121,7 +121,7 @@
|
||||
},
|
||||
{
|
||||
"name":"org.signal.libsignal.net.ChatConnection$ListenerBridge",
|
||||
"methods":[{"name":"onConnectionInterrupted","parameterTypes":["java.lang.Throwable"] }, {"name":"onIncomingMessage","parameterTypes":["byte[]","long","long"] }, {"name":"onQueueEmpty","parameterTypes":[] }, {"name":"onReceivedAlerts","parameterTypes":["java.lang.String[]"] }]
|
||||
"methods":[{"name":"connectionInterrupted","parameterTypes":["java.lang.Throwable"] }, {"name":"onConnectionInterrupted","parameterTypes":["java.lang.Throwable"] }, {"name":"onIncomingMessage","parameterTypes":["byte[]","long","long"] }, {"name":"onQueueEmpty","parameterTypes":[] }, {"name":"onReceivedAlerts","parameterTypes":["java.lang.String[]"] }, {"name":"receivedAlerts","parameterTypes":["java.lang.String[]"] }, {"name":"receivedIncomingMessage","parameterTypes":["byte[]","long","long"] }, {"name":"receivedQueueEmpty","parameterTypes":[] }]
|
||||
},
|
||||
{
|
||||
"name":"org.signal.libsignal.net.ChatConnection$Response",
|
||||
|
||||
@ -1,26 +1 @@
|
||||
[
|
||||
{
|
||||
"interfaces":["java.sql.Connection"]
|
||||
},
|
||||
{
|
||||
"interfaces":["org.asamk.Signal"]
|
||||
},
|
||||
{
|
||||
"interfaces":["org.asamk.Signal$Configuration"]
|
||||
},
|
||||
{
|
||||
"interfaces":["org.asamk.Signal$Device"]
|
||||
},
|
||||
{
|
||||
"interfaces":["org.asamk.Signal$Group"]
|
||||
},
|
||||
{
|
||||
"interfaces":["org.asamk.Signal$Identity"]
|
||||
},
|
||||
{
|
||||
"interfaces":["org.asamk.SignalControl"]
|
||||
},
|
||||
{
|
||||
"interfaces":["org.freedesktop.dbus.interfaces.DBus"]
|
||||
}
|
||||
]
|
||||
[{"interfaces":["java.sql.Connection"]},{"interfaces":["org.asamk.Signal"]},{"interfaces":["org.asamk.Signal$Configuration"]},{"interfaces":["org.asamk.Signal$Device"]},{"interfaces":["org.asamk.Signal$Group"]},{"interfaces":["org.asamk.Signal$Identity"]},{"interfaces":["org.asamk.SignalControl"]},{"interfaces":["org.freedesktop.dbus.interfaces.DBus"]}]
|
||||
|
||||
9429
graalvm-config-dir/reachability-metadata.json
Normal file
9429
graalvm-config-dir/reachability-metadata.json
Normal file
File diff suppressed because it is too large
Load Diff
@ -1832,6 +1832,15 @@
|
||||
"name":"org.bouncycastle.jcajce.provider.drbg.DRBG$Mappings",
|
||||
"methods":[{"name":"<init>","parameterTypes":[] }]
|
||||
},
|
||||
{
|
||||
"name":"org.bouncycastle.jcajce.provider.kdf.HKDF$Mappings"
|
||||
},
|
||||
{
|
||||
"name":"org.bouncycastle.jcajce.provider.kdf.PBEPBKDF2$Mappings"
|
||||
},
|
||||
{
|
||||
"name":"org.bouncycastle.jcajce.provider.kdf.SCRYPT$Mappings"
|
||||
},
|
||||
{
|
||||
"name":"org.bouncycastle.jcajce.provider.keystore.BC$Mappings",
|
||||
"methods":[{"name":"<init>","parameterTypes":[] }]
|
||||
@ -1919,6 +1928,10 @@
|
||||
"name":"org.bouncycastle.jcajce.provider.symmetric.HC256$Mappings",
|
||||
"methods":[{"name":"<init>","parameterTypes":[] }]
|
||||
},
|
||||
{
|
||||
"name":"org.bouncycastle.jcajce.provider.symmetric.HKDF$Mappings",
|
||||
"methods":[{"name":"<init>","parameterTypes":[] }]
|
||||
},
|
||||
{
|
||||
"name":"org.bouncycastle.jcajce.provider.symmetric.IDEA$Mappings",
|
||||
"methods":[{"name":"<init>","parameterTypes":[] }]
|
||||
@ -2172,199 +2185,199 @@
|
||||
"queryAllDeclaredConstructors":true
|
||||
},
|
||||
{
|
||||
"name":"org.signal.storageservice.protos.groups.AccessControl",
|
||||
"name":"org.signal.storageservice.storage.protos.groups.AccessControl",
|
||||
"fields":[{"name":"addFromInviteLink_"}, {"name":"attributes_"}, {"name":"members_"}]
|
||||
},
|
||||
{
|
||||
"name":"org.signal.storageservice.protos.groups.AvatarUploadAttributes",
|
||||
"name":"org.signal.storageservice.storage.protos.groups.AvatarUploadAttributes",
|
||||
"fields":[{"name":"acl_"}, {"name":"algorithm_"}, {"name":"credential_"}, {"name":"date_"}, {"name":"key_"}, {"name":"policy_"}, {"name":"signature_"}]
|
||||
},
|
||||
{
|
||||
"name":"org.signal.storageservice.protos.groups.BannedMember",
|
||||
"name":"org.signal.storageservice.storage.protos.groups.BannedMember",
|
||||
"fields":[{"name":"timestamp_"}, {"name":"userId_"}]
|
||||
},
|
||||
{
|
||||
"name":"org.signal.storageservice.protos.groups.Group",
|
||||
"name":"org.signal.storageservice.storage.protos.groups.Group",
|
||||
"fields":[{"name":"accessControl_"}, {"name":"announcementsOnly_"}, {"name":"avatar_"}, {"name":"bannedMembers_"}, {"name":"description_"}, {"name":"disappearingMessagesTimer_"}, {"name":"inviteLinkPassword_"}, {"name":"members_"}, {"name":"pendingMembers_"}, {"name":"publicKey_"}, {"name":"requestingMembers_"}, {"name":"revision_"}, {"name":"title_"}]
|
||||
},
|
||||
{
|
||||
"name":"org.signal.storageservice.protos.groups.GroupAttributeBlob",
|
||||
"name":"org.signal.storageservice.storage.protos.groups.GroupAttributeBlob",
|
||||
"fields":[{"name":"contentCase_"}, {"name":"content_"}]
|
||||
},
|
||||
{
|
||||
"name":"org.signal.storageservice.protos.groups.GroupChange",
|
||||
"name":"org.signal.storageservice.storage.protos.groups.GroupChange",
|
||||
"fields":[{"name":"actions_"}, {"name":"changeEpoch_"}, {"name":"serverSignature_"}]
|
||||
},
|
||||
{
|
||||
"name":"org.signal.storageservice.protos.groups.GroupChange$Actions",
|
||||
"name":"org.signal.storageservice.storage.protos.groups.GroupChange$Actions",
|
||||
"fields":[{"name":"addBannedMembers_"}, {"name":"addMembers_"}, {"name":"addPendingMembers_"}, {"name":"addRequestingMembers_"}, {"name":"deleteBannedMembers_"}, {"name":"deleteMembers_"}, {"name":"deletePendingMembers_"}, {"name":"deleteRequestingMembers_"}, {"name":"modifyAddFromInviteLinkAccess_"}, {"name":"modifyAnnouncementsOnly_"}, {"name":"modifyAttributesAccess_"}, {"name":"modifyAvatar_"}, {"name":"modifyDescription_"}, {"name":"modifyDisappearingMessagesTimer_"}, {"name":"modifyInviteLinkPassword_"}, {"name":"modifyMemberAccess_"}, {"name":"modifyMemberProfileKeys_"}, {"name":"modifyMemberRoles_"}, {"name":"modifyTitle_"}, {"name":"promotePendingMembers_"}, {"name":"promotePendingPniAciMembers_"}, {"name":"promoteRequestingMembers_"}, {"name":"revision_"}, {"name":"sourceServiceId_"}, {"name":"sourceUuid_"}]
|
||||
},
|
||||
{
|
||||
"name":"org.signal.storageservice.protos.groups.GroupChange$Actions$AddBannedMemberAction",
|
||||
"name":"org.signal.storageservice.storage.protos.groups.GroupChange$Actions$AddBannedMemberAction",
|
||||
"fields":[{"name":"added_"}]
|
||||
},
|
||||
{
|
||||
"name":"org.signal.storageservice.protos.groups.GroupChange$Actions$AddMemberAction",
|
||||
"name":"org.signal.storageservice.storage.protos.groups.GroupChange$Actions$AddMemberAction",
|
||||
"fields":[{"name":"added_"}, {"name":"joinFromInviteLink_"}]
|
||||
},
|
||||
{
|
||||
"name":"org.signal.storageservice.protos.groups.GroupChange$Actions$AddPendingMemberAction",
|
||||
"name":"org.signal.storageservice.storage.protos.groups.GroupChange$Actions$AddPendingMemberAction",
|
||||
"fields":[{"name":"added_"}]
|
||||
},
|
||||
{
|
||||
"name":"org.signal.storageservice.protos.groups.GroupChange$Actions$AddRequestingMemberAction",
|
||||
"name":"org.signal.storageservice.storage.protos.groups.GroupChange$Actions$AddRequestingMemberAction",
|
||||
"fields":[{"name":"added_"}]
|
||||
},
|
||||
{
|
||||
"name":"org.signal.storageservice.protos.groups.GroupChange$Actions$DeleteBannedMemberAction",
|
||||
"name":"org.signal.storageservice.storage.protos.groups.GroupChange$Actions$DeleteBannedMemberAction",
|
||||
"fields":[{"name":"deletedUserId_"}]
|
||||
},
|
||||
{
|
||||
"name":"org.signal.storageservice.protos.groups.GroupChange$Actions$DeleteMemberAction",
|
||||
"name":"org.signal.storageservice.storage.protos.groups.GroupChange$Actions$DeleteMemberAction",
|
||||
"fields":[{"name":"deletedUserId_"}]
|
||||
},
|
||||
{
|
||||
"name":"org.signal.storageservice.protos.groups.GroupChange$Actions$DeletePendingMemberAction",
|
||||
"name":"org.signal.storageservice.storage.protos.groups.GroupChange$Actions$DeletePendingMemberAction",
|
||||
"fields":[{"name":"deletedUserId_"}]
|
||||
},
|
||||
{
|
||||
"name":"org.signal.storageservice.protos.groups.GroupChange$Actions$DeleteRequestingMemberAction",
|
||||
"name":"org.signal.storageservice.storage.protos.groups.GroupChange$Actions$DeleteRequestingMemberAction",
|
||||
"fields":[{"name":"deletedUserId_"}]
|
||||
},
|
||||
{
|
||||
"name":"org.signal.storageservice.protos.groups.GroupChange$Actions$ModifyAddFromInviteLinkAccessControlAction",
|
||||
"name":"org.signal.storageservice.storage.protos.groups.GroupChange$Actions$ModifyAddFromInviteLinkAccessControlAction",
|
||||
"fields":[{"name":"addFromInviteLinkAccess_"}]
|
||||
},
|
||||
{
|
||||
"name":"org.signal.storageservice.protos.groups.GroupChange$Actions$ModifyAnnouncementsOnlyAction",
|
||||
"name":"org.signal.storageservice.storage.protos.groups.GroupChange$Actions$ModifyAnnouncementsOnlyAction",
|
||||
"fields":[{"name":"announcementsOnly_"}]
|
||||
},
|
||||
{
|
||||
"name":"org.signal.storageservice.protos.groups.GroupChange$Actions$ModifyAttributesAccessControlAction",
|
||||
"name":"org.signal.storageservice.storage.protos.groups.GroupChange$Actions$ModifyAttributesAccessControlAction",
|
||||
"fields":[{"name":"attributesAccess_"}]
|
||||
},
|
||||
{
|
||||
"name":"org.signal.storageservice.protos.groups.GroupChange$Actions$ModifyAvatarAction",
|
||||
"name":"org.signal.storageservice.storage.protos.groups.GroupChange$Actions$ModifyAvatarAction",
|
||||
"fields":[{"name":"avatar_"}]
|
||||
},
|
||||
{
|
||||
"name":"org.signal.storageservice.protos.groups.GroupChange$Actions$ModifyDescriptionAction",
|
||||
"name":"org.signal.storageservice.storage.protos.groups.GroupChange$Actions$ModifyDescriptionAction",
|
||||
"fields":[{"name":"description_"}]
|
||||
},
|
||||
{
|
||||
"name":"org.signal.storageservice.protos.groups.GroupChange$Actions$ModifyDisappearingMessagesTimerAction",
|
||||
"name":"org.signal.storageservice.storage.protos.groups.GroupChange$Actions$ModifyDisappearingMessagesTimerAction",
|
||||
"fields":[{"name":"timer_"}]
|
||||
},
|
||||
{
|
||||
"name":"org.signal.storageservice.protos.groups.GroupChange$Actions$ModifyInviteLinkPasswordAction",
|
||||
"name":"org.signal.storageservice.storage.protos.groups.GroupChange$Actions$ModifyInviteLinkPasswordAction",
|
||||
"fields":[{"name":"inviteLinkPassword_"}]
|
||||
},
|
||||
{
|
||||
"name":"org.signal.storageservice.protos.groups.GroupChange$Actions$ModifyMemberProfileKeyAction",
|
||||
"name":"org.signal.storageservice.storage.protos.groups.GroupChange$Actions$ModifyMemberProfileKeyAction",
|
||||
"fields":[{"name":"presentation_"}, {"name":"profileKey_"}, {"name":"userId_"}]
|
||||
},
|
||||
{
|
||||
"name":"org.signal.storageservice.protos.groups.GroupChange$Actions$ModifyMemberRoleAction",
|
||||
"name":"org.signal.storageservice.storage.protos.groups.GroupChange$Actions$ModifyMemberRoleAction",
|
||||
"fields":[{"name":"role_"}, {"name":"userId_"}]
|
||||
},
|
||||
{
|
||||
"name":"org.signal.storageservice.protos.groups.GroupChange$Actions$ModifyMembersAccessControlAction",
|
||||
"name":"org.signal.storageservice.storage.protos.groups.GroupChange$Actions$ModifyMembersAccessControlAction",
|
||||
"fields":[{"name":"membersAccess_"}]
|
||||
},
|
||||
{
|
||||
"name":"org.signal.storageservice.protos.groups.GroupChange$Actions$ModifyTitleAction",
|
||||
"name":"org.signal.storageservice.storage.protos.groups.GroupChange$Actions$ModifyTitleAction",
|
||||
"fields":[{"name":"title_"}]
|
||||
},
|
||||
{
|
||||
"name":"org.signal.storageservice.protos.groups.GroupChange$Actions$PromotePendingMemberAction",
|
||||
"name":"org.signal.storageservice.storage.protos.groups.GroupChange$Actions$PromotePendingMemberAction",
|
||||
"fields":[{"name":"presentation_"}, {"name":"profileKey_"}, {"name":"userId_"}]
|
||||
},
|
||||
{
|
||||
"name":"org.signal.storageservice.protos.groups.GroupChange$Actions$PromotePendingPniAciMemberProfileKeyAction",
|
||||
"name":"org.signal.storageservice.storage.protos.groups.GroupChange$Actions$PromotePendingPniAciMemberProfileKeyAction",
|
||||
"fields":[{"name":"pni_"}, {"name":"presentation_"}, {"name":"profileKey_"}, {"name":"userId_"}]
|
||||
},
|
||||
{
|
||||
"name":"org.signal.storageservice.protos.groups.GroupChange$Actions$PromoteRequestingMemberAction",
|
||||
"name":"org.signal.storageservice.storage.protos.groups.GroupChange$Actions$PromoteRequestingMemberAction",
|
||||
"fields":[{"name":"role_"}, {"name":"userId_"}]
|
||||
},
|
||||
{
|
||||
"name":"org.signal.storageservice.protos.groups.GroupChanges",
|
||||
"name":"org.signal.storageservice.storage.protos.groups.GroupChanges",
|
||||
"fields":[{"name":"groupChanges_"}]
|
||||
},
|
||||
{
|
||||
"name":"org.signal.storageservice.protos.groups.GroupChanges$GroupChangeState",
|
||||
"name":"org.signal.storageservice.storage.protos.groups.GroupChanges$GroupChangeState",
|
||||
"fields":[{"name":"groupChange_"}, {"name":"groupState_"}]
|
||||
},
|
||||
{
|
||||
"name":"org.signal.storageservice.protos.groups.GroupInviteLink",
|
||||
"name":"org.signal.storageservice.storage.protos.groups.GroupInviteLink",
|
||||
"fields":[{"name":"contentsCase_"}, {"name":"contents_"}]
|
||||
},
|
||||
{
|
||||
"name":"org.signal.storageservice.protos.groups.GroupInviteLink$GroupInviteLinkContentsV1",
|
||||
"name":"org.signal.storageservice.storage.protos.groups.GroupInviteLink$GroupInviteLinkContentsV1",
|
||||
"fields":[{"name":"groupMasterKey_"}, {"name":"inviteLinkPassword_"}]
|
||||
},
|
||||
{
|
||||
"name":"org.signal.storageservice.protos.groups.GroupJoinInfo",
|
||||
"name":"org.signal.storageservice.storage.protos.groups.GroupJoinInfo",
|
||||
"fields":[{"name":"addFromInviteLink_"}, {"name":"avatar_"}, {"name":"description_"}, {"name":"memberCount_"}, {"name":"pendingAdminApproval_"}, {"name":"publicKey_"}, {"name":"revision_"}, {"name":"title_"}]
|
||||
},
|
||||
{
|
||||
"name":"org.signal.storageservice.protos.groups.Member",
|
||||
"name":"org.signal.storageservice.storage.protos.groups.Member",
|
||||
"fields":[{"name":"joinedAtRevision_"}, {"name":"presentation_"}, {"name":"profileKey_"}, {"name":"role_"}, {"name":"userId_"}]
|
||||
},
|
||||
{
|
||||
"name":"org.signal.storageservice.protos.groups.PendingMember",
|
||||
"name":"org.signal.storageservice.storage.protos.groups.PendingMember",
|
||||
"fields":[{"name":"addedByUserId_"}, {"name":"member_"}, {"name":"timestamp_"}]
|
||||
},
|
||||
{
|
||||
"name":"org.signal.storageservice.protos.groups.RequestingMember",
|
||||
"name":"org.signal.storageservice.storage.protos.groups.RequestingMember",
|
||||
"fields":[{"name":"presentation_"}, {"name":"profileKey_"}, {"name":"timestamp_"}, {"name":"userId_"}]
|
||||
},
|
||||
{
|
||||
"name":"org.signal.storageservice.protos.groups.local.DecryptedApproveMember",
|
||||
"name":"org.signal.storageservice.storage.protos.groups.local.DecryptedApproveMember",
|
||||
"fields":[{"name":"role_"}, {"name":"uuid_"}]
|
||||
},
|
||||
{
|
||||
"name":"org.signal.storageservice.protos.groups.local.DecryptedBannedMember",
|
||||
"name":"org.signal.storageservice.storage.protos.groups.local.DecryptedBannedMember",
|
||||
"fields":[{"name":"serviceIdBinary_"}, {"name":"serviceIdBytes_"}, {"name":"timestamp_"}]
|
||||
},
|
||||
{
|
||||
"name":"org.signal.storageservice.protos.groups.local.DecryptedGroup",
|
||||
"name":"org.signal.storageservice.storage.protos.groups.local.DecryptedGroup",
|
||||
"fields":[{"name":"accessControl_"}, {"name":"avatar_"}, {"name":"bannedMembers_"}, {"name":"description_"}, {"name":"disappearingMessagesTimer_"}, {"name":"inviteLinkPassword_"}, {"name":"isAnnouncementGroup_"}, {"name":"members_"}, {"name":"pendingMembers_"}, {"name":"requestingMembers_"}, {"name":"revision_"}, {"name":"title_"}]
|
||||
},
|
||||
{
|
||||
"name":"org.signal.storageservice.protos.groups.local.DecryptedGroupChange",
|
||||
"name":"org.signal.storageservice.storage.protos.groups.local.DecryptedGroupChange",
|
||||
"fields":[{"name":"deleteBannedMembers_"}, {"name":"deleteMembers_"}, {"name":"deletePendingMembers_"}, {"name":"deleteRequestingMembers_"}, {"name":"editorServiceIdBytes_"}, {"name":"editor_"}, {"name":"modifiedProfileKeys_"}, {"name":"modifyMemberRoles_"}, {"name":"newAttributeAccess_"}, {"name":"newAvatar_"}, {"name":"newBannedMembers_"}, {"name":"newDescription_"}, {"name":"newInviteLinkAccess_"}, {"name":"newInviteLinkPassword_"}, {"name":"newIsAnnouncementGroup_"}, {"name":"newMemberAccess_"}, {"name":"newMembers_"}, {"name":"newPendingMembers_"}, {"name":"newRequestingMembers_"}, {"name":"newTimer_"}, {"name":"newTitle_"}, {"name":"promotePendingMembers_"}, {"name":"promotePendingPniAciMembers_"}, {"name":"promoteRequestingMembers_"}, {"name":"revision_"}]
|
||||
},
|
||||
{
|
||||
"name":"org.signal.storageservice.protos.groups.local.DecryptedGroupJoinInfo",
|
||||
"name":"org.signal.storageservice.storage.protos.groups.local.DecryptedGroupJoinInfo",
|
||||
"fields":[{"name":"addFromInviteLink_"}, {"name":"avatar_"}, {"name":"description_"}, {"name":"isAnnouncementGroup_"}, {"name":"memberCount_"}, {"name":"pendingAdminApproval_"}, {"name":"revision_"}, {"name":"title_"}]
|
||||
},
|
||||
{
|
||||
"name":"org.signal.storageservice.protos.groups.local.DecryptedMember",
|
||||
"name":"org.signal.storageservice.storage.protos.groups.local.DecryptedMember",
|
||||
"fields":[{"name":"aciBytes_"}, {"name":"joinedAtRevision_"}, {"name":"pniBytes_"}, {"name":"pni_"}, {"name":"profileKey_"}, {"name":"role_"}, {"name":"uuid_"}]
|
||||
},
|
||||
{
|
||||
"name":"org.signal.storageservice.protos.groups.local.DecryptedModifyMemberRole",
|
||||
"name":"org.signal.storageservice.storage.protos.groups.local.DecryptedModifyMemberRole",
|
||||
"fields":[{"name":"role_"}, {"name":"uuid_"}]
|
||||
},
|
||||
{
|
||||
"name":"org.signal.storageservice.protos.groups.local.DecryptedPendingMember",
|
||||
"name":"org.signal.storageservice.storage.protos.groups.local.DecryptedPendingMember",
|
||||
"fields":[{"name":"addedByAci_"}, {"name":"addedByUuid_"}, {"name":"role_"}, {"name":"serviceIdBinary_"}, {"name":"serviceIdBytes_"}, {"name":"serviceIdCipherText_"}, {"name":"timestamp_"}, {"name":"uuidCipherText_"}]
|
||||
},
|
||||
{
|
||||
"name":"org.signal.storageservice.protos.groups.local.DecryptedPendingMemberRemoval",
|
||||
"name":"org.signal.storageservice.storage.protos.groups.local.DecryptedPendingMemberRemoval",
|
||||
"fields":[{"name":"uuidCipherText_"}]
|
||||
},
|
||||
{
|
||||
"name":"org.signal.storageservice.protos.groups.local.DecryptedRequestingMember",
|
||||
"name":"org.signal.storageservice.storage.protos.groups.local.DecryptedRequestingMember",
|
||||
"fields":[{"name":"aciBytes_"}, {"name":"profileKey_"}, {"name":"timestamp_"}, {"name":"uuid_"}]
|
||||
},
|
||||
{
|
||||
"name":"org.signal.storageservice.protos.groups.local.DecryptedString",
|
||||
"name":"org.signal.storageservice.storage.protos.groups.local.DecryptedString",
|
||||
"fields":[{"name":"value_"}]
|
||||
},
|
||||
{
|
||||
"name":"org.signal.storageservice.protos.groups.local.DecryptedTimer",
|
||||
"name":"org.signal.storageservice.storage.protos.groups.local.DecryptedTimer",
|
||||
"fields":[{"name":"duration_"}]
|
||||
},
|
||||
{
|
||||
@ -2426,6 +2439,13 @@
|
||||
"queryAllDeclaredConstructors":true,
|
||||
"methods":[{"name":"<init>","parameterTypes":["java.lang.String","java.lang.String"] }, {"name":"<init>","parameterTypes":["java.lang.String","java.lang.String","int","kotlin.jvm.internal.DefaultConstructorMarker"] }]
|
||||
},
|
||||
{
|
||||
"name":"org.whispersystems.signalservice.api.link.SetDeviceNameRequest",
|
||||
"allDeclaredFields":true,
|
||||
"queryAllDeclaredMethods":true,
|
||||
"queryAllDeclaredConstructors":true,
|
||||
"methods":[{"name":"<init>","parameterTypes":["java.lang.String"] }, {"name":"getDeviceName","parameterTypes":[] }]
|
||||
},
|
||||
{
|
||||
"name":"org.whispersystems.signalservice.api.messages.calls.HangupMessage",
|
||||
"allDeclaredFields":true,
|
||||
@ -3068,6 +3088,7 @@
|
||||
{
|
||||
"name":"org.whispersystems.signalservice.internal.storage.protos.AccountRecord",
|
||||
"allDeclaredFields":true,
|
||||
"fields":[{"name":"avatarColor"}, {"name":"avatarUrlPath"}, {"name":"backupSubscriberData"}, {"name":"backupTier"}, {"name":"backupTierHistory"}, {"name":"displayBadgesOnProfile"}, {"name":"familyName"}, {"name":"givenName"}, {"name":"hasBackup"}, {"name":"hasCompletedUsernameOnboarding"}, {"name":"hasSeenGroupStoryEducationSheet"}, {"name":"hasSetMyStoriesPrivacy"}, {"name":"hasViewedOnboardingStory"}, {"name":"keepMutedChatsArchived"}, {"name":"linkPreviews"}, {"name":"noteToSelfArchived"}, {"name":"noteToSelfMarkedUnread"}, {"name":"notificationProfileManualOverride"}, {"name":"payments"}, {"name":"phoneNumberSharingMode"}, {"name":"pinnedConversations"}, {"name":"preferContactAvatars"}, {"name":"preferredReactionEmoji"}, {"name":"primarySendsSms"}, {"name":"profileKey"}, {"name":"readReceipts"}, {"name":"sealedSenderIndicators"}, {"name":"storiesDisabled"}, {"name":"storyViewReceiptsEnabled"}, {"name":"subscriberCurrencyCode"}, {"name":"subscriberId"}, {"name":"subscriptionManuallyCancelled"}, {"name":"typingIndicators"}, {"name":"universalExpireTimer"}, {"name":"unlistedPhoneNumber"}, {"name":"username"}, {"name":"usernameLink"}],
|
||||
"methods":[{"name":"adapter","parameterTypes":[] }, {"name":"unknownFields","parameterTypes":[] }]
|
||||
},
|
||||
{
|
||||
@ -3106,6 +3127,7 @@
|
||||
{
|
||||
"name":"org.whispersystems.signalservice.internal.storage.protos.ContactRecord",
|
||||
"allDeclaredFields":true,
|
||||
"fields":[{"name":"aci"}, {"name":"aciBinary"}, {"name":"archived"}, {"name":"avatarColor"}, {"name":"blocked"}, {"name":"e164"}, {"name":"familyName"}, {"name":"givenName"}, {"name":"hidden"}, {"name":"hideStory"}, {"name":"identityKey"}, {"name":"identityState"}, {"name":"markedUnread"}, {"name":"mutedUntilTimestamp"}, {"name":"nickname"}, {"name":"note"}, {"name":"pni"}, {"name":"pniBinary"}, {"name":"pniSignatureVerified"}, {"name":"profileKey"}, {"name":"systemFamilyName"}, {"name":"systemGivenName"}, {"name":"systemNickname"}, {"name":"unregisteredAtTimestamp"}, {"name":"username"}, {"name":"whitelisted"}],
|
||||
"methods":[{"name":"adapter","parameterTypes":[] }, {"name":"unknownFields","parameterTypes":[] }]
|
||||
},
|
||||
{
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -1,18 +1,18 @@
|
||||
[versions]
|
||||
slf4j = "2.0.17"
|
||||
junit = "6.0.1"
|
||||
junit = "6.0.2"
|
||||
|
||||
[libraries]
|
||||
bouncycastle = "org.bouncycastle:bcprov-jdk18on:1.82"
|
||||
bouncycastle = "org.bouncycastle:bcprov-jdk18on:1.83"
|
||||
jackson-databind = "com.fasterxml.jackson.core:jackson-databind:2.20.1"
|
||||
argparse4j = "net.sourceforge.argparse4j:argparse4j:0.9.0"
|
||||
dbusjava = "com.github.hypfvieh:dbus-java-transport-native-unixsocket:5.0.0"
|
||||
slf4j-api = { module = "org.slf4j:slf4j-api", version.ref = "slf4j" }
|
||||
slf4j-jul = { module = "org.slf4j:jul-to-slf4j", version.ref = "slf4j" }
|
||||
logback = "ch.qos.logback:logback-classic:1.5.21"
|
||||
logback = "ch.qos.logback:logback-classic:1.5.25"
|
||||
|
||||
signalservice = "com.github.turasa:signal-service-java:2.15.3_unofficial_135"
|
||||
sqlite = "org.xerial:sqlite-jdbc:3.51.0.0"
|
||||
signalservice = "com.github.turasa:signal-service-java:2.15.3_unofficial_136"
|
||||
sqlite = "org.xerial:sqlite-jdbc:3.51.1.0"
|
||||
hikari = "com.zaxxer:HikariCP:7.0.2"
|
||||
junit-jupiter-bom = { module = "org.junit:junit-bom", version.ref = "junit" }
|
||||
junit-jupiter = { module = "org.junit.jupiter:junit-jupiter", version.ref = "junit" }
|
||||
|
||||
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@ -1,6 +1,6 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.0-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-9.3.0-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
||||
@ -4,8 +4,8 @@ plugins {
|
||||
}
|
||||
|
||||
java {
|
||||
sourceCompatibility = JavaVersion.VERSION_21
|
||||
targetCompatibility = JavaVersion.VERSION_21
|
||||
sourceCompatibility = JavaVersion.VERSION_25
|
||||
targetCompatibility = JavaVersion.VERSION_25
|
||||
|
||||
if (!JavaVersion.current().isCompatibleWith(targetCompatibility)) {
|
||||
toolchain {
|
||||
|
||||
@ -154,6 +154,8 @@ public interface Manager extends Closeable {
|
||||
|
||||
List<Device> getLinkedDevices() throws IOException;
|
||||
|
||||
void updateLinkedDevice(int deviceId, String name) throws IOException, NotPrimaryDeviceException;
|
||||
|
||||
void removeLinkedDevices(int deviceId) throws IOException, NotPrimaryDeviceException;
|
||||
|
||||
void addDeviceLink(DeviceLinkUrl linkUri) throws IOException, InvalidDeviceLinkException, NotPrimaryDeviceException, DeviceLimitExceededException;
|
||||
|
||||
@ -0,0 +1,20 @@
|
||||
package org.asamk.signal.manager.actions;
|
||||
|
||||
import org.asamk.signal.manager.helper.Context;
|
||||
|
||||
public class RetrieveDeviceNameAction implements HandleAction {
|
||||
|
||||
private static final RetrieveDeviceNameAction INSTANCE = new RetrieveDeviceNameAction();
|
||||
|
||||
public static RetrieveDeviceNameAction create() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
private RetrieveDeviceNameAction() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Context context) throws Throwable {
|
||||
context.getAccountHelper().refreshDeviceName();
|
||||
}
|
||||
}
|
||||
@ -4,8 +4,8 @@ import org.asamk.signal.manager.groups.GroupLinkPassword;
|
||||
import org.signal.core.util.Base64;
|
||||
import org.signal.libsignal.zkgroup.InvalidInputException;
|
||||
import org.signal.libsignal.zkgroup.groups.GroupMasterKey;
|
||||
import org.signal.storageservice.protos.groups.GroupInviteLink;
|
||||
import org.signal.storageservice.protos.groups.local.DecryptedGroup;
|
||||
import org.signal.storageservice.storage.protos.groups.GroupInviteLink;
|
||||
import org.signal.storageservice.storage.protos.groups.local.DecryptedGroup;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
@ -52,8 +52,8 @@ public final class GroupInviteLinkUrl {
|
||||
var bytes = Base64.decode(encoding);
|
||||
GroupInviteLink groupInviteLink = GroupInviteLink.ADAPTER.decode(bytes);
|
||||
|
||||
if (groupInviteLink.v1Contents != null) {
|
||||
var groupInviteLinkContentsV1 = groupInviteLink.v1Contents;
|
||||
if (groupInviteLink.contentsV1 != null) {
|
||||
var groupInviteLinkContentsV1 = groupInviteLink.contentsV1;
|
||||
var groupMasterKey = new GroupMasterKey(groupInviteLinkContentsV1.groupMasterKey.toByteArray());
|
||||
var password = GroupLinkPassword.fromBytes(groupInviteLinkContentsV1.inviteLinkPassword.toByteArray());
|
||||
|
||||
@ -90,7 +90,7 @@ public final class GroupInviteLinkUrl {
|
||||
}
|
||||
|
||||
private static String createUrl(GroupMasterKey groupMasterKey, GroupLinkPassword password) {
|
||||
var groupInviteLink = new GroupInviteLink.Builder().v1Contents(new GroupInviteLink.GroupInviteLinkContentsV1.Builder().groupMasterKey(
|
||||
var groupInviteLink = new GroupInviteLink.Builder().contentsV1(new GroupInviteLink.GroupInviteLinkContentsV1.Builder().groupMasterKey(
|
||||
ByteString.of(groupMasterKey.serialize()))
|
||||
.inviteLinkPassword(ByteString.of(password.serialize()))
|
||||
.build()).build();
|
||||
|
||||
@ -522,6 +522,22 @@ public class AccountHelper {
|
||||
account.setEncryptedDeviceName(encryptedDeviceName);
|
||||
}
|
||||
|
||||
public void setDeviceName(int deviceId, String deviceName) throws IOException {
|
||||
final var privateKey = account.getAciIdentityKeyPair().getPrivateKey();
|
||||
final var encryptedDeviceName = DeviceNameUtil.encryptDeviceName(deviceName, privateKey);
|
||||
handleResponseException(dependencies.getLinkDeviceApi().setDeviceName(encryptedDeviceName, deviceId));
|
||||
context.getSyncHelper().sendDeviceNameChange(deviceId);
|
||||
}
|
||||
|
||||
public void refreshDeviceName() throws IOException {
|
||||
final var devices = handleResponseException(dependencies.getLinkDeviceApi().getDevices());
|
||||
final var deviceId = account.getDeviceId();
|
||||
final var device = devices.stream().filter(d -> d.id == deviceId).findFirst();
|
||||
if (device.isPresent()) {
|
||||
account.setEncryptedDeviceName(device.get().name);
|
||||
}
|
||||
}
|
||||
|
||||
public void updateAccountAttributes() throws IOException {
|
||||
handleResponseException(dependencies.getAccountApi().setAccountAttributes(account.getAccountAttributes(null)));
|
||||
}
|
||||
|
||||
@ -34,10 +34,10 @@ import org.signal.libsignal.zkgroup.groups.GroupMasterKey;
|
||||
import org.signal.libsignal.zkgroup.groups.GroupSecretParams;
|
||||
import org.signal.libsignal.zkgroup.groupsend.GroupSendEndorsementsResponse;
|
||||
import org.signal.libsignal.zkgroup.profiles.ProfileKey;
|
||||
import org.signal.storageservice.protos.groups.GroupChangeResponse;
|
||||
import org.signal.storageservice.protos.groups.local.DecryptedGroup;
|
||||
import org.signal.storageservice.protos.groups.local.DecryptedGroupChange;
|
||||
import org.signal.storageservice.protos.groups.local.DecryptedGroupJoinInfo;
|
||||
import org.signal.storageservice.storage.protos.groups.GroupChangeResponse;
|
||||
import org.signal.storageservice.storage.protos.groups.local.DecryptedGroup;
|
||||
import org.signal.storageservice.storage.protos.groups.local.DecryptedGroupChange;
|
||||
import org.signal.storageservice.storage.protos.groups.local.DecryptedGroupJoinInfo;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.whispersystems.signalservice.api.groupsv2.DecryptedGroupChangeLog;
|
||||
@ -192,9 +192,9 @@ public class GroupHelper {
|
||||
final GroupInfoV2 groupInfoV2,
|
||||
final GroupChangeResponse groupChangeResponse
|
||||
) {
|
||||
if (groupChangeResponse.groupSendEndorsementsResponse.size() > 0) {
|
||||
if (groupChangeResponse.group_send_endorsements_response.size() > 0) {
|
||||
try {
|
||||
final var groupSendEndorsementsResponse = new GroupSendEndorsementsResponse(groupChangeResponse.groupSendEndorsementsResponse.toByteArray());
|
||||
final var groupSendEndorsementsResponse = new GroupSendEndorsementsResponse(groupChangeResponse.group_send_endorsements_response.toByteArray());
|
||||
|
||||
updateGroupEndorsements(groupInfoV2.getGroupId(),
|
||||
groupInfoV2.getMasterKey(),
|
||||
@ -391,7 +391,7 @@ public class GroupHelper {
|
||||
.joinGroup(inviteLinkUrl.getGroupMasterKey(), inviteLinkUrl.getPassword(), groupJoinInfo);
|
||||
final var group = getOrMigrateGroup(inviteLinkUrl.getGroupMasterKey(),
|
||||
groupJoinInfo.revision + 1,
|
||||
changeResponse.groupChange == null ? null : changeResponse.groupChange.encode());
|
||||
changeResponse.group_change == null ? null : changeResponse.group_change.encode());
|
||||
|
||||
if (group.getGroup() == null) {
|
||||
// Only requested member, can't send update to group members
|
||||
@ -873,10 +873,10 @@ public class GroupHelper {
|
||||
|
||||
final var groupChangeResponse = groupGroupChangePair.second();
|
||||
handleGroupChangeResponse(groupInfoV2, groupChangeResponse);
|
||||
if (groupChangeResponse.groupChange == null) {
|
||||
if (groupChangeResponse.group_change == null) {
|
||||
throw new AssertionError("groupChange is null");
|
||||
}
|
||||
var messageBuilder = getGroupUpdateMessageBuilder(groupInfoV2, groupChangeResponse.groupChange.encode());
|
||||
var messageBuilder = getGroupUpdateMessageBuilder(groupInfoV2, groupChangeResponse.group_change.encode());
|
||||
return sendGroupMessage(messageBuilder,
|
||||
groupInfoV2.getMembersIncludingPendingWithout(account.getSelfRecipientId()),
|
||||
groupInfoV2);
|
||||
@ -924,10 +924,10 @@ public class GroupHelper {
|
||||
members.addAll(group.getMembersIncludingPendingWithout(selfRecipientId));
|
||||
account.getGroupStore().updateGroup(group);
|
||||
|
||||
if (groupChangeResponse.groupChange == null) {
|
||||
if (groupChangeResponse.group_change == null) {
|
||||
throw new AssertionError("groupChange is null");
|
||||
}
|
||||
final var messageBuilder = getGroupUpdateMessageBuilder(group, groupChangeResponse.groupChange.encode());
|
||||
final var messageBuilder = getGroupUpdateMessageBuilder(group, groupChangeResponse.group_change.encode());
|
||||
return sendGroupMessage(messageBuilder, members, group);
|
||||
}
|
||||
|
||||
|
||||
@ -21,15 +21,15 @@ import org.signal.libsignal.zkgroup.groups.GroupMasterKey;
|
||||
import org.signal.libsignal.zkgroup.groups.GroupSecretParams;
|
||||
import org.signal.libsignal.zkgroup.groups.UuidCiphertext;
|
||||
import org.signal.libsignal.zkgroup.profiles.ProfileKey;
|
||||
import org.signal.storageservice.protos.groups.AccessControl;
|
||||
import org.signal.storageservice.protos.groups.GroupChange;
|
||||
import org.signal.storageservice.protos.groups.GroupChangeResponse;
|
||||
import org.signal.storageservice.protos.groups.Member;
|
||||
import org.signal.storageservice.protos.groups.local.DecryptedGroup;
|
||||
import org.signal.storageservice.protos.groups.local.DecryptedGroupChange;
|
||||
import org.signal.storageservice.protos.groups.local.DecryptedGroupJoinInfo;
|
||||
import org.signal.storageservice.protos.groups.local.DecryptedMember;
|
||||
import org.signal.storageservice.protos.groups.local.DecryptedPendingMember;
|
||||
import org.signal.storageservice.storage.protos.groups.AccessControl;
|
||||
import org.signal.storageservice.storage.protos.groups.GroupChange;
|
||||
import org.signal.storageservice.storage.protos.groups.GroupChangeResponse;
|
||||
import org.signal.storageservice.storage.protos.groups.Member;
|
||||
import org.signal.storageservice.storage.protos.groups.local.DecryptedGroup;
|
||||
import org.signal.storageservice.storage.protos.groups.local.DecryptedGroupChange;
|
||||
import org.signal.storageservice.storage.protos.groups.local.DecryptedGroupJoinInfo;
|
||||
import org.signal.storageservice.storage.protos.groups.local.DecryptedMember;
|
||||
import org.signal.storageservice.storage.protos.groups.local.DecryptedPendingMember;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.whispersystems.signalservice.api.groupsv2.DecryptChangeVerificationMode;
|
||||
@ -225,7 +225,7 @@ class GroupV2Helper {
|
||||
change.modifyAvatar(new GroupChange.Actions.ModifyAvatarAction.Builder().avatar(avatarCdnKey).build());
|
||||
}
|
||||
|
||||
change.sourceServiceId(getSelfAci().toByteString());
|
||||
change.sourceUserId(getSelfAci().toByteString());
|
||||
|
||||
return commitChange(groupInfoV2, change);
|
||||
}
|
||||
@ -252,7 +252,7 @@ class GroupV2Helper {
|
||||
final var aci = getSelfAci();
|
||||
final var change = groupOperations.createModifyGroupMembershipChange(candidates, bannedUuids, aci);
|
||||
|
||||
change.sourceServiceId(getSelfAci().toByteString());
|
||||
change.sourceUserId(getSelfAci().toByteString());
|
||||
|
||||
return commitChange(groupInfoV2, change);
|
||||
}
|
||||
@ -343,7 +343,7 @@ class GroupV2Helper {
|
||||
false,
|
||||
groupInfoV2.getGroup().bannedMembers);
|
||||
|
||||
change.sourceServiceId(getSelfAci().toByteString());
|
||||
change.sourceUserId(getSelfAci().toByteString());
|
||||
|
||||
return commitChange(groupInfoV2, change);
|
||||
}
|
||||
@ -360,7 +360,7 @@ class GroupV2Helper {
|
||||
|
||||
final var change = groupOperations.createUnbanServiceIdsChange(serviceIds);
|
||||
|
||||
change.sourceServiceId(getSelfAci().toByteString());
|
||||
change.sourceUserId(getSelfAci().toByteString());
|
||||
|
||||
return commitChange(groupInfoV2, change);
|
||||
}
|
||||
@ -436,7 +436,7 @@ class GroupV2Helper {
|
||||
|
||||
final GroupsV2Operations.GroupOperations groupOperations = getGroupOperations(groupInfoV2);
|
||||
final var change = groupOperations.createUpdateProfileKeyCredentialChange(profileKeyCredential);
|
||||
change.sourceServiceId(getSelfAci().toByteString());
|
||||
change.sourceUserId(getSelfAci().toByteString());
|
||||
return commitChange(groupInfoV2, change);
|
||||
}
|
||||
|
||||
@ -459,7 +459,7 @@ class GroupV2Helper {
|
||||
? groupOperations.createGroupJoinRequest(profileKeyCredential)
|
||||
: groupOperations.createGroupJoinDirect(profileKeyCredential);
|
||||
|
||||
change.sourceServiceId(context.getRecipientHelper()
|
||||
change.sourceUserId(context.getRecipientHelper()
|
||||
.resolveSignalServiceAddress(selfRecipientId)
|
||||
.getServiceId()
|
||||
.toByteString());
|
||||
@ -479,7 +479,7 @@ class GroupV2Helper {
|
||||
final var change = groupOperations.createAcceptInviteChange(profileKeyCredential);
|
||||
|
||||
final var aci = context.getRecipientHelper().resolveSignalServiceAddress(selfRecipientId).getServiceId();
|
||||
change.sourceServiceId(aci.toByteString());
|
||||
change.sourceUserId(aci.toByteString());
|
||||
|
||||
return commitChange(groupInfoV2, change);
|
||||
}
|
||||
@ -585,7 +585,7 @@ class GroupV2Helper {
|
||||
final var groupOperations = dependencies.getGroupsV2Operations().forGroup(groupSecretParams);
|
||||
final var previousGroupState = groupInfoV2.getGroup();
|
||||
final var nextRevision = previousGroupState.revision + 1;
|
||||
final var changeActions = change.revision(nextRevision).build();
|
||||
final var changeActions = change.version(nextRevision).build();
|
||||
final DecryptedGroupChange decryptedChange;
|
||||
final DecryptedGroup decryptedGroupState;
|
||||
|
||||
@ -611,7 +611,7 @@ class GroupV2Helper {
|
||||
GroupLinkPassword password
|
||||
) throws IOException {
|
||||
final var nextRevision = currentRevision + 1;
|
||||
final var changeActions = change.revision(nextRevision).build();
|
||||
final var changeActions = change.version(nextRevision).build();
|
||||
|
||||
return dependencies.getGroupsV2Api()
|
||||
.patchGroup(changeActions,
|
||||
@ -621,6 +621,9 @@ class GroupV2Helper {
|
||||
|
||||
Pair<ServiceId, ProfileKey> getAuthoritativeProfileKeyFromChange(final DecryptedGroupChange change) {
|
||||
UUID editor = UuidUtil.fromByteStringOrNull(change.editorServiceIdBytes);
|
||||
if (editor == null) {
|
||||
return null;
|
||||
}
|
||||
final var editorProfileKeyBytes = Stream.concat(Stream.of(change.newMembers.stream(),
|
||||
change.promotePendingMembers.stream(),
|
||||
change.modifiedProfileKeys.stream())
|
||||
|
||||
@ -5,6 +5,7 @@ import org.asamk.signal.manager.actions.HandleAction;
|
||||
import org.asamk.signal.manager.actions.RefreshPreKeysAction;
|
||||
import org.asamk.signal.manager.actions.RenewSessionAction;
|
||||
import org.asamk.signal.manager.actions.ResendMessageAction;
|
||||
import org.asamk.signal.manager.actions.RetrieveDeviceNameAction;
|
||||
import org.asamk.signal.manager.actions.RetrieveProfileAction;
|
||||
import org.asamk.signal.manager.actions.SendGroupInfoAction;
|
||||
import org.asamk.signal.manager.actions.SendGroupInfoRequestAction;
|
||||
@ -633,6 +634,12 @@ public final class IncomingMessageHandler {
|
||||
context.getAccountHelper().handlePniChangeNumberMessage(pniChangeNumber, updatedPni);
|
||||
}
|
||||
}
|
||||
if (syncMessage.getDeviceNameChange().isPresent()) {
|
||||
final var deviceNameChange = syncMessage.getDeviceNameChange().get();
|
||||
if (deviceNameChange.deviceId != null && deviceNameChange.deviceId == account.getDeviceId()) {
|
||||
actions.add(RetrieveDeviceNameAction.create());
|
||||
}
|
||||
}
|
||||
return actions;
|
||||
}
|
||||
|
||||
|
||||
@ -52,6 +52,8 @@ import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import okio.ByteString;
|
||||
|
||||
public class SyncHelper {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(SyncHelper.class);
|
||||
@ -406,6 +408,11 @@ public class SyncHelper {
|
||||
return context.getSendHelper().sendSyncMessage(SignalServiceSyncMessage.forMessageRequestResponse(response));
|
||||
}
|
||||
|
||||
public SendMessageResult sendDeviceNameChange(final int deviceId) {
|
||||
final var deviceNameChange = new SyncMessage.DeviceNameChange(deviceId, ByteString.EMPTY);
|
||||
return context.getSendHelper().sendSyncMessage(SignalServiceSyncMessage.forDeviceNameChange(deviceNameChange));
|
||||
}
|
||||
|
||||
private SendMessageResult requestSyncData(final SyncMessage.Request.Type type) {
|
||||
var r = new SyncMessage.Request.Builder().type(type).build();
|
||||
var message = SignalServiceSyncMessage.forRequest(new RequestMessage(r));
|
||||
|
||||
@ -20,7 +20,7 @@ public class JobExecutor implements AutoCloseable {
|
||||
|
||||
public JobExecutor(final Context context) {
|
||||
this.context = context;
|
||||
this.executorService = Executors.newCachedThreadPool();
|
||||
this.executorService = Executors.newVirtualThreadPerTaskExecutor();
|
||||
}
|
||||
|
||||
public void enqueueJob(Job job) {
|
||||
|
||||
@ -157,7 +157,7 @@ public class ManagerImpl implements Manager {
|
||||
private final SignalDependencies dependencies;
|
||||
private final Context context;
|
||||
|
||||
private final ExecutorService executor = Executors.newCachedThreadPool();
|
||||
private final ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor();
|
||||
|
||||
private Thread receiveThread;
|
||||
private boolean isReceivingSynchronous;
|
||||
@ -487,6 +487,21 @@ public class ManagerImpl implements Manager {
|
||||
}).toList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateLinkedDevice(
|
||||
final int deviceId,
|
||||
final String name
|
||||
) throws IOException, NotPrimaryDeviceException {
|
||||
if (deviceId == account.getDeviceId()) {
|
||||
context.getAccountHelper().setDeviceName(name);
|
||||
} else {
|
||||
if (!account.isPrimaryDevice()) {
|
||||
throw new NotPrimaryDeviceException();
|
||||
}
|
||||
context.getAccountHelper().setDeviceName(deviceId, name);
|
||||
}
|
||||
}
|
||||
|
||||
private Long getPlaintextCreatedAt(DeviceInfo d) {
|
||||
final var DECRYPTION_INFO = "deviceCreatedAt";
|
||||
var identityKey = account.getAciIdentityKeyPair().getPrivateKey();
|
||||
|
||||
@ -8,10 +8,10 @@ import org.asamk.signal.manager.storage.recipients.RecipientId;
|
||||
import org.asamk.signal.manager.storage.recipients.RecipientResolver;
|
||||
import org.signal.core.models.ServiceId;
|
||||
import org.signal.libsignal.zkgroup.groups.GroupMasterKey;
|
||||
import org.signal.storageservice.protos.groups.AccessControl;
|
||||
import org.signal.storageservice.protos.groups.Member;
|
||||
import org.signal.storageservice.protos.groups.local.DecryptedGroup;
|
||||
import org.signal.storageservice.protos.groups.local.EnabledState;
|
||||
import org.signal.storageservice.storage.protos.groups.AccessControl;
|
||||
import org.signal.storageservice.storage.protos.groups.Member;
|
||||
import org.signal.storageservice.storage.protos.groups.local.DecryptedGroup;
|
||||
import org.signal.storageservice.storage.protos.groups.local.EnabledState;
|
||||
import org.whispersystems.signalservice.api.push.DistributionId;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
@ -16,7 +16,7 @@ import org.signal.libsignal.zkgroup.InvalidInputException;
|
||||
import org.signal.libsignal.zkgroup.groups.GroupMasterKey;
|
||||
import org.signal.libsignal.zkgroup.groups.GroupSecretParams;
|
||||
import org.signal.libsignal.zkgroup.groupsend.GroupSendEndorsement;
|
||||
import org.signal.storageservice.protos.groups.local.DecryptedGroup;
|
||||
import org.signal.storageservice.storage.protos.groups.local.DecryptedGroup;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.whispersystems.signalservice.api.push.DistributionId;
|
||||
|
||||
@ -16,7 +16,7 @@ import org.signal.core.models.ServiceId;
|
||||
import org.signal.core.util.Hex;
|
||||
import org.signal.libsignal.zkgroup.InvalidInputException;
|
||||
import org.signal.libsignal.zkgroup.groups.GroupMasterKey;
|
||||
import org.signal.storageservice.protos.groups.local.DecryptedGroup;
|
||||
import org.signal.storageservice.storage.protos.groups.local.DecryptedGroup;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.whispersystems.signalservice.api.push.DistributionId;
|
||||
|
||||
@ -32,7 +32,7 @@ fi
|
||||
|
||||
run() {
|
||||
# To update graalvm config, set GRAALVM_HOME, e.g:
|
||||
# export GRAALVM_HOME=/usr/lib/jvm/java-21-graalvm
|
||||
# export GRAALVM_HOME=/usr/lib/jvm/java-25-graalvm
|
||||
if [ ! -z "$GRAALVM_HOME" ]; then
|
||||
export JAVA_HOME=$GRAALVM_HOME
|
||||
export SIGNAL_CLI_OPTS="-agentlib:native-image-agent=config-merge-dir=graalvm-config-dir-${SIGNAL_CLI_AGENT_ID}/"
|
||||
|
||||
@ -1,7 +1,14 @@
|
||||
dependencyResolutionManagement {
|
||||
repositories {
|
||||
mavenLocal()
|
||||
mavenCentral()
|
||||
mavenLocal()
|
||||
maven {
|
||||
name = "SignalBuildArtifacts"
|
||||
url = uri("https://build-artifacts.signal.org/libraries/maven/")
|
||||
content {
|
||||
includeGroupByRegex("org\\.signal.*")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -143,9 +143,6 @@ public interface Signal extends DBusInterface {
|
||||
String avatar
|
||||
) throws Error.AttachmentInvalid, Error.Failure, Error.InvalidNumber, Error.GroupNotFound, Error.InvalidGroupId;
|
||||
|
||||
@Deprecated
|
||||
boolean isRegistered() throws Error.Failure, Error.InvalidNumber;
|
||||
|
||||
boolean isRegistered(String number) throws Error.Failure, Error.InvalidNumber;
|
||||
|
||||
List<Boolean> isRegistered(List<String> numbers) throws Error.Failure, Error.InvalidNumber;
|
||||
|
||||
@ -13,10 +13,4 @@ public enum ServiceEnvironmentCli {
|
||||
return "staging";
|
||||
}
|
||||
},
|
||||
@Deprecated SANDBOX {
|
||||
@Override
|
||||
public String toString() {
|
||||
return "sandbox";
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
@ -3,12 +3,13 @@ package org.asamk.signal.commands;
|
||||
import org.asamk.signal.OutputType;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.SequencedCollection;
|
||||
|
||||
public interface Command {
|
||||
|
||||
String getName();
|
||||
|
||||
default List<OutputType> getSupportedOutputTypes() {
|
||||
default SequencedCollection<OutputType> getSupportedOutputTypes() {
|
||||
return List.of(OutputType.PLAIN_TEXT);
|
||||
}
|
||||
}
|
||||
|
||||
@ -58,6 +58,7 @@ public class Commands {
|
||||
addCommand(new UpdateAccountCommand());
|
||||
addCommand(new UpdateConfigurationCommand());
|
||||
addCommand(new UpdateContactCommand());
|
||||
addCommand(new UpdateDeviceCommand());
|
||||
addCommand(new UpdateGroupCommand());
|
||||
addCommand(new UpdateProfileCommand());
|
||||
addCommand(new UploadStickerPackCommand());
|
||||
|
||||
@ -10,6 +10,7 @@ import org.asamk.signal.ReceiveMessageHandler;
|
||||
import org.asamk.signal.Shutdown;
|
||||
import org.asamk.signal.commands.exceptions.CommandException;
|
||||
import org.asamk.signal.commands.exceptions.IOErrorException;
|
||||
import org.asamk.signal.commands.exceptions.UserErrorException;
|
||||
import org.asamk.signal.dbus.DbusHandler;
|
||||
import org.asamk.signal.http.HttpServerHandler;
|
||||
import org.asamk.signal.json.JsonReceiveMessageHandler;
|
||||
@ -31,6 +32,7 @@ import java.nio.channels.Channel;
|
||||
import java.nio.channels.ServerSocketChannel;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.SequencedCollection;
|
||||
|
||||
import static org.asamk.signal.util.CommandUtil.getReceiveConfig;
|
||||
|
||||
@ -86,7 +88,7 @@ public class DaemonCommand implements MultiLocalCommand, LocalCommand {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<OutputType> getSupportedOutputTypes() {
|
||||
public SequencedCollection<OutputType> getSupportedOutputTypes() {
|
||||
return List.of(OutputType.PLAIN_TEXT, OutputType.JSON);
|
||||
}
|
||||
|
||||
@ -201,9 +203,7 @@ public class DaemonCommand implements MultiLocalCommand, LocalCommand {
|
||||
&& tcpAddress == null
|
||||
&& httpAddress == null
|
||||
&& inheritedChannel == null) {
|
||||
logger.warn(
|
||||
"Running daemon command without explicit mode is deprecated. Use 'daemon --dbus' to use the dbus interface.");
|
||||
daemonHandler.runDbus(false, DbusConfig.getBusname());
|
||||
throw new UserErrorException("At least one channel parameter is required, e.g. --socket or --dbus.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -16,6 +16,7 @@ import org.asamk.signal.output.JsonWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.SequencedCollection;
|
||||
|
||||
public class DeleteLocalAccountDataCommand implements RegistrationCommand, JsonRpcRegistrationCommand<Map<String, Object>> {
|
||||
|
||||
@ -54,7 +55,7 @@ public class DeleteLocalAccountDataCommand implements RegistrationCommand, JsonR
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<OutputType> getSupportedOutputTypes() {
|
||||
public SequencedCollection<OutputType> getSupportedOutputTypes() {
|
||||
return List.of(OutputType.PLAIN_TEXT, OutputType.JSON);
|
||||
}
|
||||
|
||||
|
||||
@ -5,6 +5,7 @@ import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import org.asamk.signal.OutputType;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.SequencedCollection;
|
||||
|
||||
public interface JsonRpcCommand<T> extends Command {
|
||||
|
||||
@ -12,7 +13,7 @@ public interface JsonRpcCommand<T> extends Command {
|
||||
return null;
|
||||
}
|
||||
|
||||
default List<OutputType> getSupportedOutputTypes() {
|
||||
default SequencedCollection<OutputType> getSupportedOutputTypes() {
|
||||
return List.of(OutputType.JSON);
|
||||
}
|
||||
}
|
||||
|
||||
@ -21,6 +21,7 @@ import java.io.FileInputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.channels.Channels;
|
||||
import java.util.List;
|
||||
import java.util.SequencedCollection;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import static org.asamk.signal.util.CommandUtil.getReceiveConfig;
|
||||
@ -53,7 +54,7 @@ public class JsonRpcDispatcherCommand implements LocalCommand, MultiLocalCommand
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<OutputType> getSupportedOutputTypes() {
|
||||
public SequencedCollection<OutputType> getSupportedOutputTypes() {
|
||||
return List.of(OutputType.JSON);
|
||||
}
|
||||
|
||||
|
||||
@ -11,6 +11,7 @@ import org.asamk.signal.output.JsonWriter;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.SequencedCollection;
|
||||
|
||||
public interface JsonRpcLocalCommand extends JsonRpcSingleCommand<Map<String, Object>>, LocalCommand {
|
||||
|
||||
@ -23,7 +24,7 @@ public interface JsonRpcLocalCommand extends JsonRpcSingleCommand<Map<String, Ob
|
||||
handleCommand(commandNamespace, m, jsonWriter);
|
||||
}
|
||||
|
||||
default List<OutputType> getSupportedOutputTypes() {
|
||||
default SequencedCollection<OutputType> getSupportedOutputTypes() {
|
||||
return List.of(OutputType.PLAIN_TEXT, OutputType.JSON);
|
||||
}
|
||||
}
|
||||
|
||||
@ -11,6 +11,7 @@ import org.asamk.signal.output.JsonWriter;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.SequencedCollection;
|
||||
|
||||
public interface JsonRpcMultiLocalCommand extends JsonRpcMultiCommand<Map<String, Object>>, MultiLocalCommand {
|
||||
|
||||
@ -27,7 +28,7 @@ public interface JsonRpcMultiLocalCommand extends JsonRpcMultiCommand<Map<String
|
||||
handleCommand(commandNamespace, c, jsonWriter);
|
||||
}
|
||||
|
||||
default List<OutputType> getSupportedOutputTypes() {
|
||||
default SequencedCollection<OutputType> getSupportedOutputTypes() {
|
||||
return List.of(OutputType.PLAIN_TEXT, OutputType.JSON);
|
||||
}
|
||||
}
|
||||
|
||||
@ -27,6 +27,7 @@ import java.time.Duration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.SequencedCollection;
|
||||
|
||||
public class ReceiveCommand implements LocalCommand, JsonRpcSingleCommand<ReceiveCommand.ReceiveParams> {
|
||||
|
||||
@ -60,7 +61,7 @@ public class ReceiveCommand implements LocalCommand, JsonRpcSingleCommand<Receiv
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<OutputType> getSupportedOutputTypes() {
|
||||
public SequencedCollection<OutputType> getSupportedOutputTypes() {
|
||||
return List.of(OutputType.PLAIN_TEXT, OutputType.JSON);
|
||||
}
|
||||
|
||||
|
||||
@ -21,6 +21,7 @@ import org.asamk.signal.util.CommandUtil;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.SequencedCollection;
|
||||
|
||||
public class RegisterCommand implements RegistrationCommand, JsonRpcRegistrationCommand<RegisterCommand.RegistrationParams> {
|
||||
|
||||
@ -57,7 +58,7 @@ public class RegisterCommand implements RegistrationCommand, JsonRpcRegistration
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<OutputType> getSupportedOutputTypes() {
|
||||
public SequencedCollection<OutputType> getSupportedOutputTypes() {
|
||||
return List.of(OutputType.PLAIN_TEXT, OutputType.JSON);
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,50 @@
|
||||
package org.asamk.signal.commands;
|
||||
|
||||
import net.sourceforge.argparse4j.inf.Namespace;
|
||||
import net.sourceforge.argparse4j.inf.Subparser;
|
||||
|
||||
import org.asamk.signal.commands.exceptions.CommandException;
|
||||
import org.asamk.signal.commands.exceptions.IOErrorException;
|
||||
import org.asamk.signal.commands.exceptions.UserErrorException;
|
||||
import org.asamk.signal.manager.Manager;
|
||||
import org.asamk.signal.manager.api.NotPrimaryDeviceException;
|
||||
import org.asamk.signal.output.OutputWriter;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class UpdateDeviceCommand implements JsonRpcLocalCommand {
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "updateDevice";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void attachToSubparser(final Subparser subparser) {
|
||||
subparser.help("Update a linked device.");
|
||||
subparser.addArgument("-d", "--device-id", "--deviceId")
|
||||
.type(int.class)
|
||||
.required(true)
|
||||
.help("Specify the device you want to update. Use listDevices to see the deviceIds.");
|
||||
subparser.addArgument("-n", "--device-name")
|
||||
.required(true)
|
||||
.help("Specify a name to describe the given device.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCommand(
|
||||
final Namespace ns,
|
||||
final Manager m,
|
||||
final OutputWriter outputWriter
|
||||
) throws CommandException {
|
||||
try {
|
||||
final var deviceId = ns.getInt("device-id");
|
||||
final var deviceName = ns.getString("device-name");
|
||||
m.updateLinkedDevice(deviceId, deviceName);
|
||||
} catch (NotPrimaryDeviceException e) {
|
||||
throw new UserErrorException("This command doesn't work on linked devices.");
|
||||
} catch (IOException e) {
|
||||
throw new IOErrorException("Error while updating device: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -19,6 +19,7 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.SequencedCollection;
|
||||
|
||||
public class VerifyCommand implements RegistrationCommand, JsonRpcRegistrationCommand<VerifyCommand.VerifyParams> {
|
||||
|
||||
@ -50,7 +51,7 @@ public class VerifyCommand implements RegistrationCommand, JsonRpcRegistrationCo
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<OutputType> getSupportedOutputTypes() {
|
||||
public SequencedCollection<OutputType> getSupportedOutputTypes() {
|
||||
return List.of(OutputType.PLAIN_TEXT, OutputType.JSON);
|
||||
}
|
||||
|
||||
|
||||
@ -16,6 +16,7 @@ import org.asamk.signal.output.PlainTextWriter;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.SequencedCollection;
|
||||
|
||||
public class VersionCommand implements JsonRpcLocalCommand, JsonRpcMultiLocalCommand {
|
||||
|
||||
@ -25,7 +26,7 @@ public class VersionCommand implements JsonRpcLocalCommand, JsonRpcMultiLocalCom
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<OutputType> getSupportedOutputTypes() {
|
||||
public SequencedCollection<OutputType> getSupportedOutputTypes() {
|
||||
return List.of(OutputType.PLAIN_TEXT, OutputType.JSON);
|
||||
}
|
||||
|
||||
|
||||
@ -246,6 +246,14 @@ public class DbusManagerImpl implements Manager {
|
||||
}).toList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateLinkedDevice(
|
||||
final int deviceId,
|
||||
final String name
|
||||
) throws IOException, NotPrimaryDeviceException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeLinkedDevices(final int deviceId) throws IOException {
|
||||
final var devicePath = signal.getDevice(deviceId);
|
||||
|
||||
@ -675,12 +675,6 @@ public class DbusSignalImpl implements Signal, AutoCloseable {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public boolean isRegistered() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRegistered(String number) {
|
||||
var result = isRegistered(List.of(number));
|
||||
|
||||
@ -59,7 +59,7 @@ public class HttpServerHandler implements AutoCloseable {
|
||||
logger.debug("Starting HTTP server on {}", address);
|
||||
|
||||
server = HttpServer.create(address, 0);
|
||||
server.setExecutor(Executors.newCachedThreadPool());
|
||||
server.setExecutor(Executors.newVirtualThreadPerTaskExecutor());
|
||||
|
||||
server.createContext("/api/v1/rpc", this::handleRpcEndpoint);
|
||||
server.createContext("/api/v1/events", this::handleEventsEndpoint);
|
||||
|
||||
@ -55,7 +55,7 @@ public class JsonRpcReader {
|
||||
return;
|
||||
}
|
||||
|
||||
try (final var executor = Executors.newCachedThreadPool()) {
|
||||
try (final var executor = Executors.newVirtualThreadPerTaskExecutor()) {
|
||||
while (!Thread.interrupted()) {
|
||||
final var input = lineSupplier.get();
|
||||
if (input == null) {
|
||||
@ -91,7 +91,7 @@ public class JsonRpcReader {
|
||||
case JsonRpcBatchMessage jsonRpcBatchMessage -> {
|
||||
final var messages = jsonRpcBatchMessage.getMessages();
|
||||
final var responseList = new ArrayList<JsonRpcResponse>(messages.size());
|
||||
try (final var executor = Executors.newCachedThreadPool()) {
|
||||
try (final var executor = Executors.newVirtualThreadPerTaskExecutor()) {
|
||||
final var lock = new ReentrantLock();
|
||||
messages.forEach(jsonNode -> {
|
||||
final JsonRpcRequest request;
|
||||
|
||||
@ -63,7 +63,7 @@ public class SocketHandler implements AutoCloseable {
|
||||
logger.debug("Starting JSON-RPC server on {}", address);
|
||||
|
||||
listenerThread = Thread.ofPlatform().name("daemon-listener").start(() -> {
|
||||
try (final var executor = Executors.newCachedThreadPool()) {
|
||||
try (final var executor = Executors.newVirtualThreadPerTaskExecutor()) {
|
||||
logger.info("Started JSON-RPC server on {}", address);
|
||||
while (true) {
|
||||
final var connectionId = threadNumber.getAndIncrement();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user