Research
Security News
Malicious npm Package Targets Solana Developers and Hijacks Funds
A malicious npm package targets Solana developers, rerouting funds in 2% of transactions to a hardcoded address.
Uploadcare Ruby integration handles uploads and further operations with files by wrapping Upload and REST APIs.
Note that uploadcare-ruby
3.x is not backward compatible with
2.x.
Add this line to your application's Gemfile:
gem "uploadcare-ruby"
And then execute:
$ bundle
If you use api_struct
gem in your project, replace it with uploadcare-api_struct
:
gem 'uploadcare-api_struct'
and run bundle install
If already not, create your project in Uploadcare dashboard and copy its API keys from there.
Set your Uploadcare keys in config file or through environment variables:
export UPLOADCARE_PUBLIC_KEY=your_public_key
export UPLOADCARE_SECRET_KEY=your_private_key
Or configure your app yourself if you are using different way of storing keys.
Gem configuration is available in Uploadcare.configuration
. Full list of
settings can be seen in lib/uploadcare.rb
# your_config_initializer_file.rb
Uploadcare.config.public_key = "your_public_key"
Uploadcare.config.secret_key = "your_private_key"
This section contains practical usage examples. Please note, everything that follows gets way more clear once you've looked through our docs and Upload and REST API refs.
You can also find an example project here.
Using Uploadcare is simple, and here are the basics of handling files.
@file_to_upload = File.open("your-file.png")
@uc_file = Uploadcare::Uploader.upload(@file_to_upload, store: "auto")
@uc_file.uuid
# => "dc99200d-9bd6-4b43-bfa9-aa7bfaefca40"
# URL for the file, can be used with your website or app right away
@uc_file.original_file_url
# => "https://ucarecdn.com/dc99200d-9bd6-4b43-bfa9-aa7bfaefca40/your-file.png"
The store
option can have these possible values:
true
: mark the uploaded file as stored.false
: do not mark the uploaded file as stored and remove it after 24 hours."auto"
: defers the choice of storage behavior to the auto-store setting for your Uploadcare project. This is the default behavior.Your might then want to store or delete the uploaded file.
# that's how you store a file, if you have uploaded the file using store: false and changed your mind later
@uc_file.store
# => #<Uploadcare::Api::File ...
# and that works for deleting it
@uc_file.delete
# => #<Uploadcare::Api::File ...
Uploadcare supports multiple ways to upload files:
# Smart upload - detects type of passed object and picks appropriate upload method
# If you have a large file (more than 100Mb / 10485760 bytes), the uploader will automatically process it with a multipart upload
Uploadcare::Uploader.upload("https://placekitten.com/96/139", store: "auto")
There are explicit ways to select upload type:
files = [File.open("1.jpg"), File.open("1.jpg")]
Uploadcare::Uploader.upload_files(files, store: 'auto')
Uploadcare::Uploader.upload_from_url("https://placekitten.com/96/139", store: "auto")
It is possible to track progress of the upload-from-URL process. To do that, you should specify the async
option and get a token:
Uploadcare::Uploader.upload_from_url("https://placekitten.com/96/139", async: true)
# => "c6e31082-6bdc-4cb3-bef5-14dd10574d72"
After the request for uploading-from-URL is sent, you can check the progress of the upload by sending the get_upload_from_url_status
request:
Uploadcare::Uploader.get_upload_from_url_status("1251ee66-3631-4416-a2fb-96ba59f5a515")
# => Success({:size=>453543, :total=>453543, :done=>453543, :uuid=>"5c51a7fe-e45d-42a2-ba5e-79957ff4bdab", :file_id=>"5c51a7fe-e45d-42a2-ba5e-79957ff4bdab", :original_filename=>"2250", :is_image=>true, :is_stored=>false, :image_info=>{:dpi=>[96, 96], :width=>2250, :format=>"JPEG", :height=>2250, :sequence=>false, :color_mode=>"RGB", :orientation=>nil, :geo_location=>nil, :datetime_original=>nil}, :video_info=>nil, :content_info=>{:mime=>{:mime=>"image/jpeg", :type=>"image", :subtype=>"jpeg"}, :image=>{:dpi=>[96, 96], :width=>2250, :format=>"JPEG", :height=>2250, :sequence=>false, :color_mode=>"RGB", :orientation=>nil, :geo_location=>nil, :datetime_original=>nil}}, :is_ready=>true, :filename=>"2250", :mime_type=>"image/jpeg", :metadata=>{}, :status=>"success"})
In case of the async
option is disabled, uploadcare-ruby tries to request the upload status several times (depending on the max_request_tries
config param) and then returns uploaded file attributes.
# multipart upload - can be useful for files bigger than 10 mb
Uploadcare::Uploader.multipart_upload(File.open("big_file.bin"), store: true)
For the multipart upload you can pass a block to add some additional logic after each file chunk is uploaded. For example to track file uploading progress you can do something like this:
file = File.open("big_file.bin")
progress = 0
Uploadcare::Uploader.multipart_upload(file, store: true) do |options|
progress += (100.0 / options[:links_count])
puts "PROGRESS = #{progress}"
end
Output of the code above looks like:
PROGRESS = 4.545454545454546
PROGRESS = 9.090909090909092
PROGRESS = 13.636363636363637
...
Options available in a block:
You can override auto-store setting from your Uploadcare project for each upload request:
@api.upload(files, store: true) # mark the uploaded file as stored.
@api.upload(files, store: false) # do not mark the uploaded file as stored and remove it after 24 hours.
@api.upload_from_url(url, store: "auto") # defers the choice of storage behavior to the auto-store setting.
You can upload file with custom metadata, for example subsystem
and pet
:
@api.upload(files, metadata: { subsystem: 'my_subsystem', pet: 'cat' } )
@api.upload_from_url(url, metadata: { subsystem: 'my_subsystem', pet: 'cat' })
Entities are representations of objects in Uploadcare cloud.
File entity contains its metadata. It also supports include
param to include additional fields to the file object, such as: "appdata".
@file = Uploadcare::File.file("FILE_UUID", include: "appdata")
{
"datetime_removed"=>nil,
"datetime_stored"=>"2018-11-26T12:49:10.477888Z",
"datetime_uploaded"=>"2018-11-26T12:49:09.945335Z",
"is_image"=>true,
"is_ready"=>true,
"mime_type"=>"image/jpeg",
"original_file_url"=>"https://ucarecdn.com/FILE_UUID/pineapple.jpg",
"original_filename"=>"pineapple.jpg",
"size"=>642,
"url"=>"https://api.uploadcare.com/files/FILE_UUID/",
"uuid"=>"FILE_UUID",
"variations"=>nil,
"content_info"=>{
"mime"=>{
"mime"=>"image/jpeg",
"type"=>"image",
"subtype"=>"jpeg"
},
"image"=>{
"format"=>"JPEG",
"width"=>500,
"height"=>500,
"sequence"=>false,
"orientation"=>6,
"geo_location"=>{
"latitude"=>55.62013611111111,
"longitude"=>37.66299166666666
},
"datetime_original"=>"2018-08-20T08:59:50",
"dpi"=>[72, 72]
}
},
"metadata"=>{
"subsystem"=>"uploader",
"pet"=>"cat"
},
"appdata"=>{
"uc_clamav_virus_scan"=>{
"data"=>{
"infected"=>true,
"infected_with"=>"Win.Test.EICAR_HDB-1"
},
"version"=>"0.104.2",
"datetime_created"=>"2021-09-21T11:24:33.159663Z",
"datetime_updated"=>"2021-09-21T11:24:33.159663Z"
},
"remove_bg"=>{
"data"=>{
"foreground_type"=>"person"
},
"version"=>"1.0",
"datetime_created"=>"2021-07-25T12:24:33.159663Z",
"datetime_updated"=>"2021-07-25T12:24:33.159663Z"
},
"aws_rekognition_detect_labels"=>{
"data"=>{
"LabelModelVersion"=>"2.0",
"Labels"=>[
{
"Confidence"=>93.41645812988281,
"Instances"=>[],
"Name"=>"Home Decor",
"Parents"=>[]
},
{
"Confidence"=>70.75951385498047,
"Instances"=>[],
"Name"=>"Linen",
"Parents"=>[{ "Name"=>"Home Decor" }]
},
{
"Confidence"=>64.7123794555664,
"Instances"=>[],
"Name"=>"Sunlight",
"Parents"=>[]
},
{
"Confidence"=>56.264793395996094,
"Instances"=>[],
"Name"=>"Flare",
"Parents"=>[{ "Name"=>"Light" }]
},
{
"Confidence"=>50.47153854370117,
"Instances"=>[],
"Name"=>"Tree",
"Parents"=>[{ "Name"=>"Plant" }]
}
]
},
"version"=>"2016-06-27",
"datetime_created"=>"2021-09-21T11:25:31.259763Z",
"datetime_updated"=>"2021-09-21T11:27:33.359763Z"
}
}
}
@file.local_copy # copy file to local storage
@file.remote_copy # copy file to remote storage
@file.store # stores file, returns updated metadata
@file.delete #deletes file. Returns updated metadata
The File object is also can be converted if it is a document or a video file. Imagine, you have a document file:
@file = Uploadcare::File.file("FILE_UUID")
To convert it to an another file, just do:
@converted_file = @file.convert_document({ format: "png", page: "1" }, store: true)
# => {
# "uuid"=>"<NEW_FILE_UUID>"}
# ...other file info...
# }
# OR
# Failure({:"<FILE_UUID>/document/-/format/png/-/page/1/"=>"the target_format is not a supported 'to' format for this source file. <you_source_file_extension> -> png"})
Same works for video files:
@converted_file = @file.convert_video(
{
format: "ogg",
quality: "best",
cut: { start_time: "0:0:0.1", length: "end" },
size: { resize_mode: "change_ratio", width: "600", height: "400" },
thumb: { N: 1, number: 2 }
},
store: true
)
# => {
# "uuid"=>"<NEW_FILE_UUID>"}
# ...other file info...
# }
# OR
# Failure({:"<FILE_UUID>/video/-/size/600x400/preserve_ratio/-/quality/best/-/format/ogg/-/cut/0:0:0.1/end/-/thumbs~1/2/"=>"CDN Path error: Failed to parse remainder \"/preserve_ratio\" of \"size/600x400/preserve_ratio\""})
More about file conversion here. Metadata of deleted files is stored permanently.
Uploadcare::FileList
represents the whole collection of files (or it's
subset) and provides a way to iterate through it, making pagination transparent.
FileList objects can be created using Uploadcare::FileList.file_list
method.
@list = Uploadcare::FileList.file_list
# Returns instance of Uploadcare::Entity::FileList
<Hashie::Mash
next=nil
per_page=100
previous=nil
results=[
# Array of Entity::File
]
total=8>
# load last page of files
@files = @list.files
# load all files
@all_files = @list.load
This method accepts some options to control which files should be fetched and how they should be fetched:
true
or false
. When true, file list will contain only stored files. When false — only not stored.true
or false
. When true, file list will contain only removed files. When false — all except removed. Defaults to false.datetime_uploaded
, -datetime_uploaded
. Defaults to datetime_uploaded
. More info can be found here.datetime_updated
in any direction, accepts either a DateTime
object or an ISO 8601 string. When files are ordered by size, accepts non-negative integers (size in bytes). More info can be found here.Options used to create a file list can be accessed through #options
method.
Note that, once set, they don't affect file fetching process anymore and are
stored just for your convenience. That is why they are frozen.
options = {
limit: 10,
stored: true,
ordering: "-datetime_uploaded",
from: "2017-01-01T00:00:00",
}
@list = @api.file_list(options)
To simply get all associated objects:
@list.all # => returns Array of Files
Initially, FileList
is a paginated collection. It can be navigated using following methods:
@file_list = Uploadcare::FileList.file_list
# Let's assume there are 250 files in cloud. By default, UC loads 100 files. To get next 100 files, do:
@next_page = @file_list.next_page
# To get previous page:
@previous_page = @file_list.previous_page
Alternatively, it's possible to iterate through full list of groups or files with each
:
@list.each do |file|
p file.url
end
File metadata is additional, arbitrary data, associated with uploaded file. As an example, you could store unique file identifier from your system.
# Get file's metadata keys and values.
Uploadcare::FileMetadata.index('FILE_UUID')
# Get the value of a single metadata key.
Uploadcare::FileMetadata.show('FILE_UUID', 'KEY')
# Update the value of a single metadata key. If the key does not exist, it will be created.
Uploadcare::FileMetadata.update('FILE_UUID', 'KEY', 'VALUE')
# Delete a file's metadata key.
Uploadcare::FileMetadata.delete('FILE_UUID', 'KEY')
Groups are structures intended to organize sets of separate files. Each group is
assigned UUID. Note, group UUIDs include a ~#{files_count}
part at the end.
That's a requirement of our API.
# group can be created from an array of Uploadcare files (UUIDs)
@file = "134dc30c-093e-4f48-a5b9-966fe9cb1d01"
@file2 = "134dc30c-093e-4f48-a5b9-966fe9cb1d02"
@files_ary = [@file, @file2]
@group = Uploadcare::Group.create @files
# group can be stored by group ID. It means that all files of a group will be stored on Uploadcare servers permanently
Uploadcare::Group.store(group.id)
# get a file group by its ID.
Uploadcare::Group.rest_info(group.id)
# group can be deleted by group ID.
Uploadcare::Group.delete(group.id)
# Note: This operation only removes the group object itself. All the files that were part of the group are left as is.
GroupList
is a list of Group
@group_list = Uploadcare::GroupList.list
# To get an array of groups:
@groups = @group_list.all
This is a paginated list, so pagination methods apply
https://uploadcare.com/docs/api_reference/rest/webhooks/
You can use webhooks to provide notifications about your uploads to target urls. This gem lets you create and manage webhooks.
Each webhook payload can be signed with a secret (the signing_secret
option) to ensure that the request comes from the expected sender.
More info about secure webhooks here.
Uploadcare::Webhook.create(target_url: "https://example.com/listen", event: "file.uploaded", is_active: true, signing_secret: "some-secret")
Uploadcare::Webhook.update(<webhook_id>, target_url: "https://newexample.com/listen/new", event: "file.uploaded", is_active: true, signing_secret: "some-secret")
Uploadcare::Webhook.delete("https://example.com/listen")
Uploadcare::Webhook.list
The gem has a helper class to verify a webhook signature from headers —
Uploadcare::Param::WebhookSignatureVerifier
. This class accepts three
important options:
controller
,
action
and post
from the webhook_body
.UC_SIGNING_SECRET
— then no need to send it to the verifier class.X-Uc-Signature
HTTP header
in the webhook request.Using the Uploadcare::Param::WebhookSignatureVerifier
class example:
webhook_body = '{...}'
signing_secret = "12345X"
x_uc_signature_header = "v1=9b31c7dd83fdbf4a2e12b19d7f2b9d87d547672a325b9492457292db4f513c70"
Uploadcare::Param::WebhookSignatureVerifier.valid?(signing_secret: signing_secret, x_uc_signature_header: x_uc_signature_header, webhook_body: webhook_body)
You can write your verifier. Example code:
webhook_body_json = '{...}'
signing_secret = ENV['UC_SIGNING_SECRET']
x_uc_signature_header = "v1=f4d859ed2fe47b9a4fcc81693d34e58ad12366a841e58a7072c1530483689cc0"
digest = OpenSSL::Digest.new('sha256')
calculated_signature = "v1=#{OpenSSL::HMAC.hexdigest(digest, signing_secret.force_encoding("utf-8"), webhook_body_json.force_encoding("utf-8"))}"
if calculated_signature == x_uc_signature_header
puts "WebHook signature matches!"
else
puts "WebHook signature mismatch!"
end
An Add-On
is an application implemented by Uploadcare that accepts uploaded files as an input and can produce other files and/or appdata as an output.
# Execute AWS Rekognition Add-On for a given target to detect labels in an image.
# Note: Detected labels are stored in the file's appdata.
Uploadcare::Addons.ws_rekognition_detect_labels('FILE_UUID')
# Check the status of AWS Rekognition.
Uploadcare::Addons.ws_rekognition_detect_labels_status('RETURNED_ID_FROM_WS_REKOGNITION_DETECT_LABELS')
# Execute AWS Rekognition Moderation Add-On for a given target to detect moderation labels in an image.
# Note: Detected moderation labels are stored in the file's appdata.
Uploadcare::Addons.ws_rekognition_detect_moderation_labels('FILE_UUID')
# Check the status of an Add-On execution request that had been started using the Execute Add-On operation.
Uploadcare::Addons.ws_rekognition_detect_moderation_labels_status('RETURNED_ID_FROM_WS_REKOGNITION_DETECT_MODERATION_LABELS')
# ClamAV virus checking Add-On for a given target.
Uploadcare::Addons.uc_clamav_virus_scan('FILE_UUID')
# Check and purge infected file.
Uploadcare::Addons.uc_clamav_virus_scan('FILE_UUID', purge_infected: true )
# Check the status of an Add-On execution request that had been started using the Execute Add-On operation.
Uploadcare::Addons.uc_clamav_virus_scan_status('RETURNED_ID_FROM_UC_CLAMAV_VIRUS_SCAN')
# Execute remove.bg background image removal Add-On for a given target.
Uploadcare::Addons.remove_bg('FILE_UUID')
# You can pass optional parameters.
# See the full list of parameters here: https://uploadcare.com/api-refs/rest-api/v0.7.0/#operation/removeBgExecute
Uploadcare::Addons.remove_bg('FILE_UUID', crop: true, type_level: '2')
# Check the status of an Add-On execution request that had been started using the Execute Add-On operation.
Uploadcare::Addons.remove_bg_status('RETURNED_ID_FROM_REMOVE_BG')
Project
provides basic info about the connected Uploadcare project. That
object is also an Hashie::Mash, so every methods out of
these will work.
@project = Uploadcare::Project.project
# => #<Uploadcare::Api::Project collaborators=[], name="demo", pub_key="your_public_key", autostore_enabled=true>
@project.name
# => "demo"
@project.collaborators
# => []
# while that one was empty, it usually goes like this:
# [{"email": collaborator@gmail.com, "name": "Collaborator"}, {"email": collaborator@gmail.com, "name": "Collaborator"}]
After each video file upload you obtain a file identifier in UUID format. Then you can use this file identifier to convert your video in multiple ways:
Uploadcare::VideoConverter.convert(
[
{
uuid: "dc99200d-9bd6-4b43-bfa9-aa7bfaefca40",
size: { resize_mode: "change_ratio", width: "600", height: "400" },
quality: "best",
format: "ogg",
cut: { start_time: "0:0:0.0", length: "0:0:1.0" },
thumbs: { N: 2, number: 1 }
}
],
store: false
)
This method accepts options to set properties of an output file:
preserve_ratio (default)
, change_ratio
, scale_crop
or add_padding
. NOTE: you can choose to provide a single dimension (width OR height).
The value you specify for any of the dimensions should be a non-zero integer divisible by 4
normal (default)
, better
, best
, lighter
, lightest
.mp4 (default)
, webm
, ogg
.# Response
{
:result => [
{
:original_source=>"dc99200d-9bd6-4b43-bfa9-aa7bfaefca40/video/-/size/600x400/change_ratio/-/quality/best/-/format/ogg/-/cut/0:0:0.0/0:0:1.0/-/thumbs~2/1/",
:token=>911933811,
:uuid=>"6f9b88bd-625c-4d60-bfde-145fa3813d95",
:thumbnails_group_uuid=>"cf34c5a1-8fcc-4db2-9ec5-62c389e84468~2"
}
],
:problems=>{}
}
Params in the response:
To convert multiple videos just add params as a hash for each video to the first argument of the Uploadcare::VideoConverter#convert
method:
Uploadcare::VideoConverter.convert(
[
{ video_one_params }, { video_two_params }, ...
],
store: false
)
To check a status of a video processing job you can simply use appropriate method of Uploadcare::VideoConverter
:
token = 911933811
Uploadcare::VideoConverter.status(token)
token
here is a processing job token, obtained in a response of a convert video request.
# Response
{
:status => "finished",
:error => nil,
:result => {
:uuid => "dc99200d-9bd6-4b43-bfa9-aa7bfaefca40",
:thumbnails_group_uuid => "0f181f24-7551-42e5-bebc-14b15d9d3838~2"
}
}
Params in the response:
More examples and options can be found here.
After each document file upload you obtain a file identifier in UUID format.
You can use file identifier to determine the document format and possible conversion formats.
Uploadcare::DocumentConverter.info("dc99200d-9bd6-4b43-bfa9-aa7bfaefca40")
# Response
{:error=>nil, :format=>{
:name=>"jpg",
:conversion_formats=>[
{:name=>"avif"}, {:name=>"bmp"}, {:name=>"gif"}, {:name=>"ico"}, {:name=>"pcx"}, {:name=>"pdf"}, {:name=>"png"}, {:name=>"ps"}, {:name=>"svg"}, {:name=>"tga"}, {:name=>"thumbnail"}, {:name=>"tiff"}, {:name=>"wbmp"}, {:name=>"webp"}
]
}}
Then you can use this file identifier to convert your document to a new format:
Uploadcare::DocumentConverter.convert(
[
{
uuid: "dc99200d-9bd6-4b43-bfa9-aa7bfaefca40",
format: "pdf"
}
],
store: false
)
or create an image of a particular page (if using image format):
Uploadcare::DocumentConverter.convert(
[
{
uuid: "a4b9db2f-1591-4f4c-8f68-94018924525d",
format: "png",
page: 1
}
],
store: false
)
This method accepts options to set properties of an output file:
pdf
(default), doc
, docx
, xls
, xlsx
, odt
, ods
, rtf
, txt
, jpg
, png
. In case the format operation was not found, your input document will be converted to pdf
.jpg
or png
. The method will not work for any other target formats.# Response
{
:result => [
{
:original_source=>"a4b9db2f-1591-4f4c-8f68-94018924525d/document/-/format/png/-/page/1/",
:token=>21120220
:uuid=>"88fe5ada-90f1-422a-a233-3a0f3a7cf23c"
}
],
:problems=>{}
}
Params in the response:
To convert multiple documents just add params as a hash for each document to the first argument of the Uploadcare::DocumentConverter#convert
method:
Uploadcare::DocumentConverter.convert(
[
{ doc_one_params }, { doc_two_params }, ...
],
store: false
)
To check a status of a document processing job you can simply use appropriate method of Uploadcare::DocumentConverter
:
token = 21120220
Uploadcare::DocumentConverter.status(token)
token
here is a processing job token, obtained in a response of a convert document request.
# Response
{
:status => "finished",
:error => nil,
:result => {
:uuid => "a4b9db2f-1591-4f4c-8f68-94018924525d"
}
}
Params in the response:
More examples and options can be found here
You can use custom domain and CDN provider to deliver files with authenticated URLs (see original documentation).
To generate authenticated URL from the library, you should choose Uploadcare::SignedUrlGenerators::AkamaiGenerator
(or create your own generator implementation):
generator = Uploadcare::SignedUrlGenerators::AkamaiGenerator.new(cdn_host: 'example.com', secret_key: 'secret_key')
# Optional parameters: ttl: 300, algorithm: 'sha256'
generator.generate_url(uuid, acl = optional)
generator.generate_url("a7d5645e-5cd7-4046-819f-a6a2933bafe3")
# https://example.com/a7d5645e-5cd7-4046-819f-a6a2933bafe3/?token=exp=1649405263~acl=/a7d5645e-5cd7-4046-819f-a6a2933bafe3/~hmac=a989cae5342f17013677f5a0e6577fc5594cc4e238fb4c95eda36634eb47018b
# You can pass in ACL as a second parameter to generate_url. See https://uploadcare.com/docs/security/secure-delivery/#authenticated-urls for supported acl formats
generator.generate_url("a7d5645e-5cd7-4046-819f-a6a2933bafe3", '/*/')
# https://example.com/a7d5645e-5cd7-4046-819f-a6a2933bafe3/?token=exp=1649405263~acl=/*/~hmac=3ce1152c6af8864b36d4dc721f08ca3cf0b3a20278d7f849e82c6c930d48ccc1
# Optionally you can use wildcard: true to generate a wildcard acl token
generator.generate_url("a7d5645e-5cd7-4046-819f-a6a2933bafe3", wildcard: true)
# https://example.com/a7d5645e-5cd7-4046-819f-a6a2933bafe3/?token=exp=1714233449~acl=/a7d5645e-5cd7-4046-819f-a6a2933bafe3/*~hmac=a568ee2a85dd90a8a8a1ef35ea0cc0ef0acb84fe81990edd3a06eacf10a52b4e
# You can also pass in a custom ttl and algorithm to AkamaiGenerator
generator = Uploadcare::SignedUrlGenerators::AkamaiGenerator.new(cdn_host: 'example.com', secret_key: 'secret_key', ttl: 10)
generator.generate_url("a7d5645e-5cd7-4046-819f-a6a2933bafe3")
# This generates a URL that expires in 10 seconds
# https://example.com/a7d5645e-5cd7-4046-819f-a6a2933bafe3/?token=exp=1714233277~acl=/a7d5645e-5cd7-4046-819f-a6a2933bafe3/~hmac=f25343104aeced3004d2cc4d49807d8d7c732300b54b154c319da5283a871a71
FAQs
Unknown package
We found that uploadcare-ruby demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 3 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
A malicious npm package targets Solana developers, rerouting funds in 2% of transactions to a hardcoded address.
Security News
Research
Socket researchers have discovered malicious npm packages targeting crypto developers, stealing credentials and wallet data using spyware delivered through typosquats of popular cryptographic libraries.
Security News
Socket's package search now displays weekly downloads for npm packages, helping developers quickly assess popularity and make more informed decisions.