signalapp / Signal-Desktop

A private messenger for Windows, macOS, and Linux.
https://signal.org/download
GNU Affero General Public License v3.0
14.49k stars 2.63k forks source link

[Feature Request] Support 32-bit Windows #1636

Closed ghost closed 2 years ago

ghost commented 6 years ago

The desktop version for Windows only supports 64-bit Windows. Do you develop a version for 32-bit Windows in future?

scottnonnenberg commented 6 years ago

To be honest, it's not very high on our list. We have more people asking for support for different distributions of Linux. Our research indicates that the vast majority of Windows users are on 64bit installs at this point.

Maybe you could tell me more about your situation? Find others in your situation?

Dyras commented 6 years ago

Backblaze claims only 4.3% of their Windows users run 32-bit versions of their software. Assuming it's the same for Signal, it doesn't seem worth bothering with it. As Scott said, I would prefer if they found a way of keeping their Flatpak up to date so that people won't be running ancient versions in a few months.

Flexmaen commented 6 years ago

I'm using 32bit Windows and wonder if it is really so much more work supporting 32bit Windows than some Linux distribution that has much less users. 4.3% of Windows users might still be more than most Linux distributions, regarding that OSX is coming second after Windows...

Dyras commented 6 years ago

You are absolutely right that there are fewer Linux users than 32-bit Windows users. However, I'd say there are more Signal Linux users than Signal 32-bit users since Linux users are usually more tech sawy and Signal has always been a nerd program. As Scott said, they are getting more requests for a Flatpak than they are for a 32-bit Windows version. Maybe they will consider making one for 32-bit users if the interest is high when the Flatpak is out, so who knows?

My last post here, don't want to spam Scott with emails. Feel free making a thread on the forum: https://whispersystems.discoursehosting.net/

solutionweb-ch commented 6 years ago

I think you will lose less time developing a web-based solution like Whatsapp did, than developing 10 different OS versions. I also run WIN 7 32 bits and I am annoyed. Don't lose current Whatsapp/Facebook bad reputation benefits! It's time to...

Jos512 commented 6 years ago

Backblaze claims only 4.3% of their Windows users run 32-bit versions of their software. Assuming it's the same for Signal, it doesn't seem worth bothering with it.

Firefox's hardware report (source) says that 18% of FireFox users are still on 32-bit operating systems.

2018-05-08_21-07-59

There's a small decline in number of 32-bit users each quarter, but 18% is still a sizeable portion of computer users.

nkrapivin commented 6 years ago

I tried to install Signal in ReactOS. It didn't worked. Because ReactOS doesn't have 64-bit support.

a-woolf commented 6 years ago

A 32-bit client would be 100% compatible with 64-bit Windows, and would be universal. On a tiny app like this are there even any benefits to being 64-bit only? Microsoft highly recommends using 32-bit Office (on 64-bit machines), unless spreadsheets are so large they run into memory constraints. Only then is 64-bit advised.

I use 32-bit clients whenever possible (VMs, etc) for speed and reduced memory footprint, and was utterly surprised when I found that Signal was 64-bit only.

As of May 2018, Firefox shows 30%+ of users are running 32-bit Firefox , and 18%+ of users are on a 32-bit OS. (Both metrics exclude XP/Vista.) This is a sizable chunk to write off completely.

Trolldemorted commented 6 years ago

@a-woolf In general, you should avoid 32bit builds because 64bit has a plentitude of benefits, not limited to:

A more complete list is at wikipedia.

Signal-Desktop uses electron and thus is almost a full browser, not a small app. 32bit binaries would neither be faster (because they would use less registers and not cause significantly more cache misses), nor would the memory footprint increase by a noteworthy amount, since only pointers grow to the double of their size.

Flexmaen commented 5 years ago

But do we have any disadvantage? The 32bit client would run on any windows. AFAIK Riot also uses electron and runs on 32bit Windows.

Soldier4Life commented 5 years ago

I think you will lose less time developing a web-based solution like Whatsapp did, than developing 10 different OS versions. I also run WIN 7 32 bits and I am annoyed. Don't lose current Whatsapp/Facebook bad reputation benefits! It's time to...

I fully agree... kill a dozen birds with one stone. Go web-based as opposed to native apps. While most of my gear is x64, I do have a tiny Win10 32-bit tablet/hybrid I use for travel that I can no longer use Signal on. Major bummer. Web-based is definitely the way to go. I understand that there are security concerns with that... aka using a compromised or outdated browser... but that is the same for native apps... if the device is compromised or outdated, it poses increased risk. If you can't do web-based for some reason, at least do x86 for your main platform as mentioned above... then it will work on both x86 and x64 architectures.

Flexmaen commented 5 years ago

I fully agree... kill a dozen birds with one stone. Go web-based as opposed to native apps.

Nah... Web based things are slow and lack offline possibilities (in case you need to read something while disconnected). Telegram also has a native 32bit Windows app. Can't be too difficult if you can cross-compile the soure.

andrejsky commented 5 years ago

I'd like to mention a case where it's become impossible to run Signal on new(ish) hardware. Some laptops and tablets, even though the hardware is 64bit capable, have shipped with 32bit Windows 10 due to limited eMMC capacity of 32GB and perhaps other reasons. So it has become impossible to run Signal on these types of devices (prob. what also Soldier4Life above has experienced).

Soldier4Life commented 5 years ago

I fully agree... kill a dozen birds with one stone. Go web-based as opposed to native apps.

Nah... Web based things are slow and lack offline possibilities (in case you need to read something while disconnected). Telegram also has a native 32bit Windows app. Can't be too difficult if you can cross-compile the soure.

I hear you... it is definitely a trade-off between broad spectrum compatibility and features/performance. It seems like the simple solution would be to just use x86 based architecture for all of Windows Desktop... then it can run on both. Unless there is a specific reason not to do so, that I might be missing.

MagentaFocus commented 5 years ago

I doubt I will be installing new copies of an operating system just to run an program that has been working for many years. At least let us use the old app and we can bear any security issues.

openube commented 5 years ago

I am incline to agree with MagentoUno, as long as the security issues are restricted merely to the 32bit machine, and not compromising the entire signal accounts on the contact list.

psidre commented 5 years ago

I'm currently running Windows 7 32-bit and it's the only desktop PC I have. I use Signal on my phone because it has all the features I require.

I am sure I am not alone in the idea that most users do not care about the architecture of the software, but whether or not they can use it on all of their devices to stay connected.

If I had the skills, I would build a 32-bit release myself, but I do not.

It would be a lot to a lot of people to be able to have this option.

gitoss commented 5 years ago

I just wanted to install Signal on my thin laptop, too - tiny ssd, <4gb ram so it's running Win32 OS. Alas, no can do. Bye bye Signal, back to good ol' workin' Telegram. Meh.

midtempo commented 4 years ago

Listen, I am a nerd too. I own a Google Pixel 3a and will only buy phones whose bootloaders may be unlocked. My home computer runs Linux Mint.

However, I am at the mercy of my employer during weekdays. I have for years used Google Hangouts to message my wife because I can do so using the computer without having to alternate between my phone and my computer. As many of you know, Google Hangouts/Google Chat is a completely unsecured messaging system and the messages are infinitely stored on Google's servers for you to see. I would like to use Signal on my work Windows desktop computer, but it's running 32-bit Windows. This may not change for a few years when they replace the computer.

So I may be a nerd and have updated phones and a computer. But my workplace is another story. Please make it a priority to have a 32-bit Windows version. If there is already a 64-bit Windows version, is it much more work to port it to a 32-bit Windows version? Is this really an uncommon request?

If there is no 32-bit Windows version, I might want to switch to Whatsapp instead. Whatsapp is now owned by Facebook. I have never trusted Facebook and have not had a Facebook account for years.

Flexmaen commented 4 years ago

@midtempo you'd better switch to Riot.im if you want to stay with open source, this even has a federated server structure. Only downside is that you have to verify every device if you want to have encryption.

But back to Signal: Does a 32 bit version need a lot of rework, or does it just need someone who is able to compile a 32bit version without having to change a lot? In that case it would be great to have the possibility for donating for certain features.

gitoss commented 4 years ago

I've switched to Wire by now, it's evolving to a very mature oss client (https://github.com/wireapp/wire) and of course has a 32bit version (https://wire.com/en/download) ... I'd still like to use Signal for my legacy contacts, but as supporting a broad userbase isn't Signal's priority, supporting Signal isn't mine either.

a-woolf commented 4 years ago

A 32-bit client would be 100% compatible with 64-bit Windows, and would be universal.

ARM64 Windows 10 can run Win32 (x86) apps, but cannot run Win64 (x86-64) apps without recompiling. This reinforces the need for a Win32 build - universal compatibility, as requested here over 2 years ago.

See: https://github.com/signalapp/Signal-Desktop/issues/3156 and https://github.com/signalapp/Signal-Desktop/issues/3745

awnz commented 4 years ago

To add yet another use case, there's also a number of Intel Atom tablets out there (the 32-bit UEFI only ones, ie Clover Trail) which can only run 32-bit Windows 10. Some of us don't have the budget to replace these.

And the above line of "Signal has always been a nerd program" is the wrong approach, and a little bit self-defeating - if you want to get things like Signal into the hands of more people and not just journalists and nerds, you need to make it more widely compatible.

erg commented 4 years ago

Tech nerd here using a Microsoft Surface Pro X with an arm64 cpu that can run x86 apps but not x64. Both arm64 or x86 builds would work for me, but neither are supported.

VSCode just released arm64 support, here's their github issue: https://github.com/microsoft/vscode/issues/33620

a-woolf commented 4 years ago

Just build the dang 32 bit version already. People have been asking for it for years now. More use cases keep coming up, as non-x86 systems can now run x86 code (but not x86-64 code).

peteremcc commented 4 years ago

Just tried setting Signal up on my Surface Pro X and was very surprised to find out that there isn't an ARM64 or 32bit version available.

Please do at least one!

Microsoft is pushing ARM64 heavily on upcoming devices, so this will be a growing issue.

scttmllmn commented 4 years ago

Just tried setting Signal up on my Surface Pro X and was very surprised to find out that there isn't an ARM64 or 32bit version available.

Please do at least one!

Microsoft is pushing ARM64 heavily on upcoming devices, so this will be a growing issue.

I'm in the exact same boat. I would love to use signal as my sole messaging service, being able to have signal double as my SMS app on my phone is great, but lacking desktop support is frustrating.

taxilian commented 4 years ago

Same problem here. Surface Pro X, want to use signal and can't.

Septa9 commented 4 years ago

I'm coaching several people working with small Atom notebooks. I would like to urge them do kick Whatsapp off their phones and switch to signal, but without a 32 bit desktop version... no chance.

dennisameling commented 3 years ago

Just tried building Signal Desktop both for arm64 and 32-bit Windows. arm64 will be a bit more difficult due to some native dependencies that need updates (got errors while running set npm_config_arch=arm64 and yarn install), so I think we'll have better chances to build for 32-bit for now.

32-bit builds successfully and boots on my Surface Pro X (arm64), but then it just keeps loading at the splash screen:

image

... at least it's a start πŸ˜‰

In package.json, under build > win, replace

      "target": [
        "nsis"
      ]

with

      "target": [
        {
          "target": "nsis",
          "arch": [
            "ia32",
            "x64"
          ]
        }
      ]

you will then get a release\win-ia32-unpacked folder which contains a 32-bit build. I'll try to work a bit more on this when I have some more time, probably in a few weeks from now.

Might get a bit closer by running set npm_config_arch=ia32, then yarn install

dennisameling commented 3 years ago

I started working on 32-bit support, it's more work than expected πŸ˜… some native modules will need to be compiled for 32-bit (and ideally arm64) as well as they're 64-bit only currently. I'm stuck at one native module, more details here: https://github.com/signalapp/Signal-Desktop/pull/4514 - would appreciate if anyone could help as I'm not familiar with Rust/GN/etc.

UPDATE September 14: think I've found the culprit for the issue mentioned above. Looks like one of ringrtc's dependencies needs an update to support x86. Details: https://github.com/signalapp/ringrtc/pull/12

Hope the Signal team will accept the PRs when they're done! πŸš€

Septa9 commented 3 years ago

Hi Dennis, glad to hear that you have taken up the fight. Not having the know-how to help you out, all I can do is to wish you good success, without too much hassle.

MagentaFocus commented 3 years ago

Hello Dennis, I'm new to Github. Thanks for looking into a 32 bit version. I can't help with the any software support. However I can make a financial donation to the project. I can't see a "sponsor" on your profile ?

dennisameling commented 3 years ago

@MagentaUno thanks! I appreciate the offer, but before accepting any donations I need to be 100% sure that the Signal team is willing to look into/approve my PRs related to 32-bit support (I'm not part of the Signal team). I'm currently waiting for one more dependency to be updated, then I'll have a better idea of how much work is left for 32-bit support.

Quite optimistic that I'm pretty close to that already. Hope to have more news within a few weeks (or whenever said dependency will be updated), will keep you posted here.

edmund3333 commented 3 years ago

would be nice to have a 32-Bit version, thanks

initself commented 3 years ago

I run Windows on a T60p which can't run anything but 32-bit architecture.

skerichards commented 3 years ago

@dennisameling Just checking to see if you've been able to make any progress. I'll keep checking back, but I guess I'll need to use Telegram.

To earlier comments in the thread, some of us are "nerds" enough that we're trying to bring our Boomer parents into the 20th century. I doubt mine are running anything above Windows XP right now, but I really want to be able to use a secure video client with them when we talk. They don't even understand what 32bit or 64bit IS and we're 3000 miles apart, doing tech support over chat - Signal of all things. And they can't figure out why it won't install.

So thank you to Dennis for at least making the attempt!

dennisameling commented 3 years ago

@skerichards Thanks for checking in. I'm very keen on getting the ball rolling here, but I'm stuck at https://github.com/signalapp/ringrtc/pull/12 where I'm waiting for a dependency (https://github.com/neon-bindings/neon) to update to Node's N-API. Once that's done, it should become a lot easier to get 32-bit/arm64 builds for ringrtc and then Signal Desktop itself.

I have all notifications turned on for the neon repo so that I know once they have a migration doc in place. You can subscribe to https://github.com/neon-bindings/neon/issues/596 to follow the progress there. Gotta say the Neon team has been doing an awesome job working towards N-API go-live - just look at the frequency at which they're releasing new versions: https://github.com/neon-bindings/neon/releases

When the migration doc is in place, I will be able to support the ringrtc maintainers migrate to the Neon N-API backend and (hopefully) get cross-compilation to 32-bit/arm64 working. It's just a matter of time, fingers crossed 🀞🏼

midtempo commented 3 years ago

I have been using WhatsApp as an alternative because it can be run on my 32-bit Windows work computer, and it works pretty much the same way as Signal. This is because WhatsApp uses Signal as the central component. Starting this February though, Facebook is changing the terms of use of WhatsApp to share more data and analytics with Facebook. This has now made this project more important.

Dennis, your work in this regard is really appreciated to those following this thread.

mMuck commented 3 years ago

WhatsApp uses Signal as the central component

Yes, we heard that they use the "same protocol". Did they proof that? It's all about the correct implementation. "And now we use 4096 bit xyz encryption which Tesla uses somewhere in their car, so your chat is secure. Fully E2EE*. Trust us."

This has now made this project more important.

You are absolutely right. One more reason. But in general it would be good to support as much as possible different versions of the yet good platform set. To give everyone (even kids) the chance to use well secured communication tools even on older hardware (at least my kids won't have the newest hardware until they buy them by themselves πŸ˜‰). So thanks for working on that long lasting topic πŸ‘.

*) for user satisfaction we backup the keys to help you restoring your device at anytime...

Flexmaen commented 3 years ago

Btw, Pidgin has a plugin for Signal: https://pidgin.im/plugins/?publisher=all&query=&type= Maybe this helps getting Signal to work on 32bit machines.

Septa9 commented 3 years ago

Btw, Pidgin has a plugin for Signal: https://pidgin.im/plugins/?publisher=all&query=&type=

If I get it right, the author of this plugin is not too optimistic:

"The new and annoying dependency of zkgroups.dll for the V2 groups is a sign they will eventually move away from the current implementation completely. It looks like with my plug-ins (signal and signald), I am basically riding dying horses. I am considering to throw things. It was fun while it lasted, though." [https://github.com/hoehermann/purple-signal/issues/1]

hoehermann commented 3 years ago

Hi there. Thanks for mentioning purple-signal. I am the author of purple-signal. I want to access signal without a resource-hogging browser solution. Long-term goal is a fully-fledged signal integration in Pidgin (with Pidgin 3 – if it ever gets released – probably supporting audio and video conferencing, too) and chatty. However, with libsignal-service-java being moved and hidden within the Signal-Android sources, libsignal-protocol-c looking abandoned and libsignal-client not deemed ready for production, I am trying to hit an elusive target which turns out to be moving rather swiftly. I will not supply users with the native binaries libsignal-service-java is depending on, especially if the number of dependencies increases. Right now with dennisameling, we are in luck, but that may change any time.

Velox0 commented 3 years ago

32 bit version when :(

dennisameling commented 3 years ago

Great news! I was able to get Signal to boot on Windows 10 32-bit (in a VM):

image

⚠️ This really only is a proof-of-concept for now!

We at least need the following PRs to be merged before the Signal team could even consider 32-bit builds:

For cross-reference: issue for Windows ARM64 support: https://github.com/signalapp/Signal-Desktop/issues/3745

I'm working from this branch: https://github.com/dennisameling/Signal-Desktop/tree/windows-multi-arch-support

βœ… All automated tests are passing after applying the PRs above:

Test logs
PS C:\Users\Admin\repos\signal-desktop> yarn test
yarn run v1.22.10
$ yarn test-node && yarn test-electron
$ electron-mocha --file test/setup-test-node.js --recursive test/app test/modules ts/test-node ts/test-both

x-attr dependency did not load successfully

  Attachments
    createWriterForNew
      √ should write file to disk and return path
    createWriterForExisting
      √ should write file to disk on given path and return path
      √ throws if relative path goes higher than root
    createReader
      √ should read file from disk
      √ throws if relative path goes higher than root
    copyIntoAttachmentsDirectory
      √ throws if passed a non-string
      √ returns a function that rejects if the source path is not a string
      √ returns a function that rejects if the source path is not in the user config directory
      √ returns a function that copies the source path into the attachments directory
    createDeleter
      √ should delete file from disk
      √ throws if relative path goes higher than root
    createName
      √ should return random file name with correct length
    getRelativePath
      √ should return correct path
    createAbsolutePathGetter
      √ combines root and relative path
      √ throws if relative path goes higher than root

  SignalMenu
    createTemplate
      macOS
        without setup options
          √ should return correct template
        with setup options
          √ should return correct template
      Windows
        without setup options
          √ should return correct template
        with setup options
          √ should return correct template
      Linux
        without setup options
          √ should return correct template
        with setup options
          √ should return correct template

  Protocol Filter
    _urlToPath
      √ returns proper file path for unix style file URI with hash
      √ returns proper file path for unix style file URI with querystring
      √ returns proper file path for unix style file URI with hash and querystring
      √ returns proper file path for file URI on windows
      √ translates from URL format to filesystem format
      √ translates from URL format to filesystem format
      √ handles SMB share path
      √ handles SMB share path on windows
      √ hands back a path with .. in it

  SpellCheck
    getLanguages
      √ works with locale and base available
      √ works with neither locale nor base available
      √ works with only base locale available
      √ works with only full locale available
      √ works with base provided and base available
      √ works with base provided and base not available

  Link previews
    #isLinkSafeToPreview
      √ returns false for invalid URLs
      √ returns false for non-HTTPS URLs
      √ returns false if the link is "sneaky"
      √ returns true for "safe" urls
    #findLinks
      √ returns all links if no caretLocation is provided
      √ includes all links if cursor is not in a link
      √ excludes a link not at the end if the caret is inside of it
      √ excludes a link not at the end if the caret is at its end
      √ excludes a link at the end of the caret is inside of it
      √ includes link at the end if cursor is at its end
    #isLinkSneaky
      √ returns true for =
      √ returns true for $
      √ returns true for +
      √ returns true for ^
      √ returns true for URLs with a length of 4097 or higher
      auth
        √ returns true for hrefs with auth (or pretend auth)
      domain
        √ returns false for all-latin domain
        √ returns false for IPv4 addresses
        √ returns true for IPv6 addresses
        √ returns true for Latin + Cyrillic domain
        √ returns true for Latin + Greek domain
        √ returns true for ASCII and non-ASCII mix
        √ returns true for Latin + High Greek domain
        √ returns true if the domain doesn't contain a .
        √ returns true if the domain has any empty labels
        √ returns true if the domain is longer than 2048 UTF-16 code points
      pathname
        √ returns false for no pathname
        √ returns false if the pathname contains valid characters
        √ returns true if the pathname contains invalid characters
      query string
        √ returns false for no query
        √ returns false if the query string contains valid characters
        √ returns true if the query string contains invalid characters
      hash
        √ returns false for no hash
        √ returns false if the hash contains valid characters
        √ returns true if the hash contains invalid characters

  Privacy
    redactPhoneNumbers
      √ should redact all phone numbers
    redactUuids
      √ should redact all uuids
    redactGroupIds
      √ should redact all group IDs
      √ should remove newlines from redacted group IDs
      √ should remove newlines from redacted group V2 IDs
    redactAll
      √ should redact all sensitive information
    _redactPath
      √ should redact file paths
      √ should redact URL-encoded paths
      √ should redact stack traces with both forward and backslashes
      √ should redact stack traces with escaped backslashes

  Attachment
    replaceUnicodeOrderOverrides
      √ should sanitize left-to-right order override character
      √ should sanitize right-to-left order override character
      √ should sanitize multiple override characters
      √ should ignore non-order-override characters (112ms)
    replaceUnicodeV2
      √ should remove all bad characters
      √ should should leave normal filename alone
      √ should handle missing fileName
    removeSchemaVersion
      √ should remove existing schema version
    migrateDataToFileSystem
      √ should write data to disk and store relative path to it
      √ should skip over (invalid) attachments without data
      √ should throw error if data is not valid

  Contact
    parseAndWriteAvatar
      √ handles message with no avatar in contact
      √ turns phone numbers to e164 format
      √ removes contact avatar if it has no sub-avatar
      √ writes avatar to disk
      √ removes number element if it ends up with no value
      √ drops address if it has no real values
      √ removes invalid elements if no values remain in contact
      √ handles a contact with just organization
    _validate
      √ returns error if contact has no name.displayName or organization
      √ logs if no values remain in contact

  Errors
    toLogFormat
      √ should return error stack trace if present
      √ should return error string representation if stack is missing
      √ should return `0` argument
      √ should return `false` argument
      √ should return `null` argument
      √ should return `undefined` argument

  Message
    createAttachmentDataWriter
      √ should ignore messages that didn’t go through attachment migration
      √ should ignore messages without attachments
      √ should write attachments to file system on original path
      √ should process quote attachment thumbnails
      √ should process contact avatars
    initializeSchemaVersion
      √ should ignore messages with previously inherited schema
      for message without attachments
        √ should initialize schema version to zero
      for message with attachments
        √ should inherit existing attachment schema version
    upgradeSchema
      √ should upgrade an unversioned message to the latest version
      with multiple upgrade steps
        √ should return last valid message when any upgrade step fails
        √ should skip out-of-order upgrade steps
    _withSchemaVersion
      √ should require a version number
      √ should require an upgrade function
      √ should skip upgrading if message has already been upgraded
      √ should return original message if upgrade function throws
      √ should return original message if upgrade function returns null
    _mapQuotedAttachments
      √ handles message with no quote
      √ handles quote with no attachments
      √ handles zero attachments
      √ handles attachments with no thumbnail
      √ does not eliminate thumbnails with missing data field
      √ calls provided async function for each quoted attachment
    _mapContact
      √ handles message with no contact field
      √ handles one contact

  MIME
    isJPEG
      √ should return true for `image/jpeg`
      √ should return false for `jpg`
      √ should return false for `jpeg`
      √ should return false for `image/jpg`
      √ should return false for `image/gif`
      √ should return false for `image/tiff`
      √ should return false for `application/json`
      √ should return false for `0`
      √ should return false for `false`
      √ should return false for `null`
      √ should return false for `undefined`

  SchemaVersion
    isValid
      √ should return true for positive integers
      √ should return false for any other value (40ms)

  LeftPane
    getRowFromIndex
      given only pinned chats
        √ returns pinned chats, not headers
      given only non-pinned chats
        √ returns conversations, not headers
      given only pinned and non-pinned chats
        √ returns headers and conversations
      given not showing archive with archived conversation
        √ returns an archive button last
      given showing archive and archive chats
        √ returns archived conversations

  groupMediaItemsByDate
    √ should group mediaItems

  license comments
    √ includes a license comment at the top of every relevant file (214ms)

  isLinkPreviewDateValid
    √ returns false for non-numbers
    √ returns false for zero
    √ returns false for NaN
    √ returns false for any infinite value
    √ returns false for timestamps more than a day from now
    √ returns true for timestamps before tomorrow

  uploadDebugLogs
    √ makes a request to get the S3 bucket, then uploads it there
    √ rejects if we can't get a token
    √ rejects with an invalid token body
    √ rejects if the upload doesn't return a 204

  logging
    #isLineAfterDate
      √ returns false if falsy
      √ returns false if invalid JSON
      √ returns false if date is invalid
      √ returns false if log time is invalid
      √ returns false if date before provided date
      √ returns true if date is after provided date
    #eliminateOutOfDateFiles
      √ deletes an empty file
      √ deletes a file with invalid JSON lines
      √ deletes a file with all dates before provided date
      √ keeps a file with first line date before provided date
      √ keeps a file with last line date before provided date
    #eliminateOldEntries
      √ eliminates all non-parsing entries
      √ preserves all lines if before target date
    #fetchLog
      √ returns error if file does not exist
      √ returns empty array if file has no valid JSON lines
      √ returns just three fields in each returned line
    #fetch
      √ returns single entry if no files
      √ returns sorted entries from all files

  MemberRepository
    #updateMembers
      √ updates with given members
    #getMemberById
      √ returns undefined when there is no search id
      √ returns a matched member
      √ returns undefined when it does not have the member
    #getMemberByUuid
      √ returns undefined when there is no search uuid
      √ returns a matched member
      √ returns undefined when it does not have the member
    #search
      given a prefix-matching string on last name
        √ returns the match
      given a prefix-matching string on first name
        √ returns the match
      given a prefix-matching string on profile name
        √ returns the match
      given a prefix-matching string on title
        √ returns the match
      given a match in the middle of a name
        √ returns zero matches

  matchMention
    √ handles an AtMentionify from clipboard
    √ handles an MentionBlot from clipboard
    √ converts a missing AtMentionify to string
    √ converts a missing MentionBlot to string
    √ passes other clipboard elements through

  getDeltaToRemoveStaleMentions
    given text
      √ retains the text
    given stale and valid mentions
      √ retains the valid and replaces the stale
    given emoji embeds
      √ retains the embeds
    given other ops
      √ passes them through

  getTextAndMentionsFromOps
    given only text
      √ returns only text trimmed
      √ returns trimmed of trailing newlines
    given text, emoji, and mentions
      √ returns the trimmed text with placeholders and mentions
    given only mentions
      √ returns the trimmed text with placeholders and mentions
      √ does not trim newlines padding mentions

  getDeltaToRestartMention
    given text and emoji
      √ returns the correct retains, a delete, and an @

  Attachment
    getUploadSizeLimitKb
      √ returns 6000 kilobytes for supported non-GIF images
      √ returns 25000 kilobytes for GIFs
      √ returns 100000 for other file types
    getFileExtension
      √ should return file extension from content type
      √ should return file extension for QuickTime videos
    getSuggestedFilename
      for attachment with filename
        √ should return existing filename if present
      for attachment without filename
        √ should generate a filename based on timestamp
      for attachment with index
        √ should generate a filename based on timestamp
    isVisualMedia
      √ should return true for images
      √ should return true for videos
      √ should return false for voice message attachment
      √ should return false for other attachments
    isFile
      √ should return true for JSON
      √ should return false for images
      √ should return false for videos
      √ should return false for voice message attachment
    isVoiceMessage
      √ should return true for voice message attachment
      √ should return true for legacy Android voice message attachment
      √ should return false for other attachments

  Contact
    getName
      √ returns displayName if provided
      √ returns organization if no displayName
      √ returns givenName + familyName if no displayName or organization
      √ returns just givenName
      √ returns just familyName
    contactSelector
      √ eliminates avatar if it has had an attachment download error
      √ does not calculate absolute path if avatar is pending
      √ calculates absolute path

  Message
    initializeAttachmentMetadata
      √ should classify visual media attachments
      √ should classify file attachments
      √ should classify voice message attachments
      √ does not include long message attachments
      √ handles not attachments

  MIME
    isGif
      √ returns true for GIFs
      √ returns false for non-GIFs

  Settings
    getAudioNotificationSupport
      √ returns native support on macOS
      √ returns no support on Windows 7
      √ returns native support on Windows 8
      √ returns custom support on Linux
    isAudioNotificationSupported
      √ returns true on macOS
      √ returns false on Windows 7
      √ returns true on Windows 8
      √ returns true on Linux
    isNotificationGroupingSupported
      √ returns true on macOS
      √ returns true on Windows 7
      √ returns true on Windows 8
      √ returns true on Linux
    isHideMenuBarSupported
      √ returns false on macOS
      √ returns true on Windows 7
      √ returns true on Windows 8
      √ returns true on Linux
    isDrawAttentionSupported
      √ returns false on macOS
      √ returns true on Windows 7
      √ returns true on Windows 8
      √ returns true on Linux

  updater/signatures
    #getVersion
      √ successfully gets version
    #getUpdateFileName
      √ successfully gets version
    #isUpdateFileNameValid
      √ returns true for normal filenames
      √ returns false for problematic names
    #validatePath
      √ succeeds for simple children
      √ returns false for problematic names

  updater/curve
    √ roundtrips
    √ verifies with our own key

  updater/signatures
    √ _getFileHash returns correct hash (54ms)
    √ roundtrips binary file writes
    √ roundtrips signature (90ms)
    √ fails signature verification if version changes (90ms)
    √ fails signature verification if signature tampered with (107ms)
    √ fails signature verification if binary file tampered with (102ms)
    √ fails signature verification if signed by different key (89ms)

  combineNames
    √ returns undefined if no names provided
    √ returns first name only if family name not provided
    √ returns returns combined names
    √ returns given name first if names in Chinese
    √ returns given name first if names in Japanese
    √ returns given name first if names in Korean

  getAnimatedPngDataIfExists
    √ returns null for empty buffers
    √ returns null for non-PNG files
    √ returns null for non-animated PNG files
    √ returns data for animated PNG files

  getOwn
    √ returns undefined when asking for a non-existent property
    √ returns undefined when asking for a non-own property
    √ returns own properties
    √ works even if `hasOwnProperty` has been overridden for the object

  getTextWithMentions
    given mention replacements
      √ replaces them
      √ sorts them to go from back to front

  getUserAgent
    √ returns the right User-Agent on Windows
    √ returns the right User-Agent on macOS
    √ returns the right User-Agent on Linux
    √ omits the platform on unsupported platforms

  isFileDangerous
    √ returns false for images
    √ returns false for documents
    √ returns true for executable files
    √ returns true for Microsoft settings files
    √ returns false for non-dangerous files that end in ".", which can happen on Windows
    √ returns true for dangerous files that end in ".", which can happen on Windows
    √ returns false for empty filename
    √ returns false for exe at various parts of filename
    √ returns true for upper-case EXE

  isMuted
    √ returns false if passed undefined
    √ returns false if passed a date in the past
    √ returns false if passed a date in the future

  isPathInside
    √ returns false if the child path is not inside the parent path
    √ returns true if the child path is inside the parent path

  LatestQueue
    √ if the queue is empty, new tasks are started immediately
    √ only enqueues the latest operation

  nonRenderedRemoteParticipant
    √ returns a video request object a width and height of 0

  normalizeGroupCallTimestamp
    √ returns undefined if passed NaN
    √ returns undefined if passed 0
    √ returns undefined if passed a negative number
    √ returns undefined if passed a string that cannot be parsed as a number
    √ returns undefined if passed a BigInt of 0
    √ returns undefined if passed a negative BigInt
    √ returns undefined if passed a non-parseable type
    √ returns positive numbers passed in
    √ parses strings as numbers
    √ only parses the first 15 characters of a string
    √ converts positive BigInts to numbers

  sgnlHref
    isSgnlHref
      √ returns false for non-strings
      √ returns false for invalid URLs
      √ returns false if the protocol is not "sgnl:"
      √ returns true if the protocol is "sgnl:"
      √ accepts URL objects
    isSignalHttpsLink
      √ returns false for non-strings
      √ returns false for invalid URLs
      √ returns false if the protocol is not "https:"
      √ returns true if the protocol is "https:"
      √ returns false if username or password are set
      √ returns false if port is set
      √ accepts URL objects
    parseSgnlHref
      √ returns a null command for invalid URLs
      √ parses the command for URLs with no arguments
      √ parses a command's arguments
      √ treats the port as part of the command
      √ ignores duplicate query parameters
      √ includes hash
      √ ignores other parts of the URL
      √ doesn't do anything fancy with arrays or objects in the query string
    parseSignalHttpsLink
      √ returns a null command for invalid URLs
      √ handles signal.art links
      √ handles signal.group links

  sleep
    √ returns a promise that resolves after the specified number of milliseconds

  sniffImageMimeType
    √ returns undefined for empty buffers
    √ returns undefined for non-image files
    √ sniffs ICO files
    √ sniffs BMP files
    √ sniffs GIF files
    √ sniffs WEBP files
    √ sniffs PNG files
    √ sniffs JPEG files
    √ handles ArrayBuffers

  sortByTitle
    √ does nothing to arrays that don't need to be sorted
    √ sorts the array by title
    √ doesn't mutate its argument

  toggleMaximizedBrowserWindow
    √ maximizes an unmaximized window
    √ unmaximizes a maximized window

  writeWindowsZoneIdentifier
    √ writes zone transfer ID 3 (internet) to the Zone.Identifier file
    √ fails if there is an existing Zone.Identifier file
    √ fails if the original file does not exist
    √ fails if not on Windows

  environment utilities
    parseEnvironment
      √ returns Environment.Production for non-strings
      √ returns Environment.Production for invalid strings
      √ parses "development" as Environment.Development
      √ parses "production" as Environment.Production
      √ parses "staging" as Environment.Staging
      √ parses "test" as Environment.Test
      √ parses "test-lib" as Environment.TestLib

  shouldUseFullSizeLinkPreviewImage
    √ returns false if there is no image
    √ returns false is the preview is a sticker pack
    √ returns false if either of the image's dimensions are missing
    √ returns false if either of the image's dimensions are <200px
    √ returns false if the image is square
    √ returns false if the image is roughly square
    √ returns false for large attachments that aren't images
    √ returns true for larger images

  cleanDataForIpc
    √ does nothing to JSON primitives
    √ does nothing to undefined
    √ converts BigInts to strings
    √ converts functions to `undefined` but does not mark them as cleaned, for backwards compatibility
    √ converts symbols to `undefined`
    √ converts ArrayBuffers to `undefined`
    √ converts valid dates to ISO strings
    √ converts invalid dates to `undefined`
    √ converts other iterables to arrays
    √ deeply cleans arrays, removing `undefined` and `null`s
    √ deeply cleans sets and converts them to arrays
    √ deeply cleans maps and converts them to objects
    √ calls `toNumber` when available
    √ deeply cleans objects with a `null` prototype
    √ deeply cleans objects with a prototype of `Object.prototype`
    √ deeply cleans class instances

  both/state/selectors/conversations
    #getConversationSelector
      √ returns empty placeholder if falsey id provided
      √ returns empty placeholder if no match
      √ returns conversation by e164 first
      √ returns conversation by uuid
      √ returns conversation by groupId
      √ returns conversation by conversationId
      √ does proper caching of result
    #getLeftPaneList
      √ sorts conversations based on timestamp then by intl-friendly title
      given pinned conversations
        √ sorts pinned conversations based on order in storage

  both/state/selectors/items
    #getPinnedConversationIds
      √ returns pinnedConversationIds key from items
      √ returns empty array if no saved data

  both/state/selectors/search
    #getMessageSearchResultSelector
      √ returns undefined if message not found in lookup
      √ returns undefined if type is unexpected
      √ returns incoming message
      √ returns outgoing message and caches appropriately

  assert
    √ does nothing if the assertion passes
    √ throws because we're in a test environment

  assignWithNoUnnecessaryAllocation
    √ returns the same object if there are no modifications
    √ returns a new object if there are modifications
    √ only performs a shallow comparison
    √ doesn't modify the original object when there are no modifications
    √ doesn't modify the original object when there are modifications

  calling notification helpers
    getCallingNotificationText
      √ says that the call has ended
      √ includes the creator's first name when describing a call
      √ if the creator doesn't have a first name, falls back to their title
      √ has a special message if you were the one to start the call
      √ handles an unknown creator

  isIterable
    √ returns false for non-iterables
    √ returns true for iterables

  makeLookup
    √ returns an empty object if passed an empty array
    √ returns an object that lets you look up objects by string key
    √ if there are duplicates, the last one wins
    √ ignores undefined properties
    √ allows key of 0
    √ converts the lookup to a string
    √ looks up own and inherited properties

  reallyJsonStringify
    √ returns the same thing as JSON.stringify when JSON.stringify returns a string
    √ returns a string when JSON.stringify returns undefined
    √ returns a string when JSON.stringify would error

  themeClassName
    √ returns "light-theme" when passed a light theme
    √ returns "dark-theme" when passed a dark theme

  version utilities
    isBeta
      √ returns false for non-beta version strings
      √ returns true for beta version strings

  both/util/webSafeBase64
    √ roundtrips with all elements
    #toWebSafeBase64
      √ replaces +
      √ replaces /
      √ removes =
    #fromWebSafeBase64
      √ replaces -
      √ replaces _
      √ adds ===
      √ adds ==
      √ adds =

  449 passing (2s)

$ yarn grunt test
$ grunt test
Running "unit-tests" task
Starting path C:\Users\Admin\repos\signal-desktop\node_modules\.bin\electron.cmd with args [ 'C:\\Users\\Admin\\repos\\signal-desktop\\main.js' ]
App started. Now waiting for test results...
>> 459 tests passed.

Running "lib-unit-tests" task
Starting path C:\Users\Admin\repos\signal-desktop\node_modules\.bin\electron.cmd with args [ 'C:\\Users\\Admin\\repos\\signal-desktop\\main.js' ]
App started. Now waiting for test results...
>> 123 tests passed.

Done.
Done in 23.69s.
hoehermann commented 3 years ago

I welcome dennisameling's win32 builds of zkgroup.dll very much. The node binary seems to be okay for node usage, but does anyone know any sources for a win32 build of signal_jni.dll for native use? My users request it, but I do not really want to build it myself.

mailinglists35 commented 3 years ago

@scottnonnenberg-signal looks like some volunteers are making progress on building signal 32 bit for windows and judging by the number of comments and participants this is not really an insignificant number of 32 bit users.

is there any plan to change this in your priority list and start working with @dennisameling to bring this into official release? there are lots of older hardware in the less developed areas that runs 32bit windows because there is no justification for a more resource hungry 64bit build on the same hardware.

a 2010 HP desktop that originally was shipped with windows xp, now runs windows 10 LTSC 32bit (receives security updates until 2029!!!) very well, but cannot use 64bit apps. except for exposing hypervisor features into a kvm guest and passing through a pci domain into a kvm guest, I've never needed 64bits on a desktop machine. all 32bit variants of the browsers run faster than their 64bit parts without missing any web features.

I understand you devs look forward into the future and the future is 64bit, but ask yourself, is this actually worth it? is it worth to leave the less developed areas/contries into the dark just because they can't afford hardware to run 64bit at decent speed?

mailinglists35 commented 3 years ago

To earlier comments in the thread, some of us are "nerds" enough that we're trying to bring our Boomer parents into the 20th century. I doubt mine are running anything above Windows XP right now, but I really want to be able to use a secure video client with them when we talk. They don't even understand what 32bit or 64bit IS and we're 3000 miles apart, doing tech support over chat - Signal of all things. And they can't figure out why it won't install.

please, get rid of that xp. it was the absolute best windows microsoft ever made but now it is a big risk of getting ransomware. if your cpu platform is Wolfdale or newer, windows 10 ltsc 32bit runs fine and you get security updates until 2029. it can do video calling and social media without problems. it's quite a pain to upgrade (xp -> vista -> 7 -> 7 enterprise -> 10 ltsb 2015 -> 10 ltsc 2019) so consider a fresh install instead on next visit.

move the OS to a SSD, add some ram if you have free dimm sockets, setup automatic updates, install an antivirus and you get a fast and automatic secure solution for your folks that doesn't need intensive maintenance until 2029!

dennisameling commented 3 years ago

Here's a production build of Signal Desktop 5.2.0 arm64+ia32 (32-bit): https://github.com/dennisameling/Signal-Desktop/releases/tag/v5.2.0

I plan to update the production builds regularly until the Signal team does, but it also means that auto-updating is disabled for now. You can either subscribe to this issue or my fork to be notified when a new version becomes available 😊

MagentaFocus commented 3 years ago

[signalapp/Signal-Desktop] [Feature Request] Support 32-bit Windows (#1636)

Hello Dennis

Thank you for the 32bit signal. I have missed signal on my PC for years now.

dennisameling on Monday, May 24, 2021, 6:31:41 AM, you wrote: +++++ [snip] +++++ Here's a production build of Signal Desktop 5.2.0 arm64+ia32 (32-bit):Β https://github.com/dennisameling/Signal-Desktop/releases/tag/v5.2.0 I plan to update the production builds regularly until the Signal team does, but it also means that auto-updating is disabled for now. You can either subscribe to this issue or my fork to be notified when a new version becomes available 😊 β€” You are receiving this because you were mentioned. Reply to this email directly,Β view it on GitHub, orΒ unsubscribe.

+++++ [end snip] +++++

RegardsΒ  BobΒ Korbel Adelaide, Australia