activestorage 7.0.0.rc3 → 7.0.2.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activestorage might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +41 -0
- data/MIT-LICENSE +1 -1
- data/app/assets/javascripts/activestorage.esm.js +5 -17
- data/app/assets/javascripts/activestorage.js +5 -17
- data/app/controllers/active_storage/blobs/proxy_controller.rb +2 -2
- data/app/controllers/active_storage/blobs/redirect_controller.rb +1 -1
- data/app/controllers/active_storage/direct_uploads_controller.rb +1 -7
- data/app/controllers/active_storage/representations/proxy_controller.rb +2 -2
- data/app/controllers/active_storage/representations/redirect_controller.rb +1 -1
- data/app/javascript/activestorage/blob_record.js +3 -10
- data/app/javascript/activestorage/direct_upload.js +2 -4
- data/app/javascript/activestorage/direct_upload_controller.js +1 -9
- data/app/models/active_storage/variant.rb +3 -3
- data/app/models/active_storage/variation.rb +1 -1
- data/db/update_migrate/20191206030411_create_active_storage_variant_records.rb +1 -1
- data/lib/active_storage/analyzer/audio_analyzer.rb +1 -1
- data/lib/active_storage/analyzer/video_analyzer.rb +1 -1
- data/lib/active_storage/attached/model.rb +4 -2
- data/lib/active_storage/engine.rb +17 -2
- data/lib/active_storage/errors.rb +0 -3
- data/lib/active_storage/gem_version.rb +2 -2
- data/lib/active_storage/previewer/video_previewer.rb +2 -0
- data/lib/active_storage.rb +1 -2
- metadata +16 -17
- data/lib/active_storage/direct_upload_token.rb +0 -59
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3d9df0f86c676632d14361aeb9d1ac834834c5888d601084408f8c07c8b52c56
|
4
|
+
data.tar.gz: f635cc43298bc0574332bd15442ad5b2922dc243773100b215badfdd54dbc5a7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f41a19838f26239a1739f1c2c977fbbf16d037eac381701b2cff6650a0704bc955835c31aa0a3be02fe061329f21c3a0b9199ed2ca8758a94af00cbecd953470
|
7
|
+
data.tar.gz: 7fae947ad43e2995c637ee3b6304702ebfc797de47fd99ddb4101e21edf6b7e026f47518bf56d0ebfdf058a324b63e8f734026d03f1e49399a81607cc5642888
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,40 @@
|
|
1
|
+
## Rails 7.0.2.1 (February 11, 2022) ##
|
2
|
+
|
3
|
+
* No changes.
|
4
|
+
|
5
|
+
|
6
|
+
## Rails 7.0.2 (February 08, 2022) ##
|
7
|
+
|
8
|
+
* Revert the ability to pass `service_name` param to `DirectUploadsController` which was introduced
|
9
|
+
in 7.0.0.
|
10
|
+
|
11
|
+
That change caused a lot of problems to upgrade Rails applications so we decided to remove it
|
12
|
+
while in work in a more backwards compatible implementation.
|
13
|
+
|
14
|
+
*Gannon McGibbon*
|
15
|
+
|
16
|
+
* Allow applications to opt out of precompiling Active Storage JavaScript assets.
|
17
|
+
|
18
|
+
*jlestavel*
|
19
|
+
|
20
|
+
|
21
|
+
## Rails 7.0.1 (January 06, 2022) ##
|
22
|
+
|
23
|
+
* No changes.
|
24
|
+
|
25
|
+
|
26
|
+
## Rails 7.0.0 (December 15, 2021) ##
|
27
|
+
|
28
|
+
* Support transforming empty-ish `has_many_attached` value into `[]` (e.g. `[""]`).
|
29
|
+
|
30
|
+
```ruby
|
31
|
+
@user.highlights = [""]
|
32
|
+
@user.highlights # => []
|
33
|
+
```
|
34
|
+
|
35
|
+
*Sean Doyle*
|
36
|
+
|
37
|
+
|
1
38
|
## Rails 7.0.0.rc3 (December 14, 2021) ##
|
2
39
|
|
3
40
|
* No changes.
|
@@ -5,6 +42,10 @@
|
|
5
42
|
|
6
43
|
## Rails 7.0.0.rc2 (December 14, 2021) ##
|
7
44
|
|
45
|
+
* No changes.
|
46
|
+
|
47
|
+
## Rails 7.0.0.rc1 (December 06, 2021) ##
|
48
|
+
|
8
49
|
* `Add ActiveStorage::Blob.compose` to concatenate multiple blobs.
|
9
50
|
|
10
51
|
*Gannon McGibbon*
|
data/MIT-LICENSE
CHANGED
@@ -508,7 +508,7 @@ function toArray(value) {
|
|
508
508
|
}
|
509
509
|
|
510
510
|
class BlobRecord {
|
511
|
-
constructor(file, checksum, url
|
511
|
+
constructor(file, checksum, url) {
|
512
512
|
this.file = file;
|
513
513
|
this.attributes = {
|
514
514
|
filename: file.name,
|
@@ -516,8 +516,6 @@ class BlobRecord {
|
|
516
516
|
byte_size: file.size,
|
517
517
|
checksum: checksum
|
518
518
|
};
|
519
|
-
this.directUploadToken = directUploadToken;
|
520
|
-
this.attachmentName = attachmentName;
|
521
519
|
this.xhr = new XMLHttpRequest;
|
522
520
|
this.xhr.open("POST", url, true);
|
523
521
|
this.xhr.responseType = "json";
|
@@ -545,9 +543,7 @@ class BlobRecord {
|
|
545
543
|
create(callback) {
|
546
544
|
this.callback = callback;
|
547
545
|
this.xhr.send(JSON.stringify({
|
548
|
-
blob: this.attributes
|
549
|
-
direct_upload_token: this.directUploadToken,
|
550
|
-
attachment_name: this.attachmentName
|
546
|
+
blob: this.attributes
|
551
547
|
}));
|
552
548
|
}
|
553
549
|
requestDidLoad(event) {
|
@@ -608,12 +604,10 @@ class BlobUpload {
|
|
608
604
|
let id = 0;
|
609
605
|
|
610
606
|
class DirectUpload {
|
611
|
-
constructor(file, url,
|
607
|
+
constructor(file, url, delegate) {
|
612
608
|
this.id = ++id;
|
613
609
|
this.file = file;
|
614
610
|
this.url = url;
|
615
|
-
this.serviceName = serviceName;
|
616
|
-
this.attachmentName = attachmentName;
|
617
611
|
this.delegate = delegate;
|
618
612
|
}
|
619
613
|
create(callback) {
|
@@ -622,7 +616,7 @@ class DirectUpload {
|
|
622
616
|
callback(error);
|
623
617
|
return;
|
624
618
|
}
|
625
|
-
const blob = new BlobRecord(this.file, checksum, this.url
|
619
|
+
const blob = new BlobRecord(this.file, checksum, this.url);
|
626
620
|
notify(this.delegate, "directUploadWillCreateBlobWithXHR", blob.xhr);
|
627
621
|
blob.create((error => {
|
628
622
|
if (error) {
|
@@ -653,7 +647,7 @@ class DirectUploadController {
|
|
653
647
|
constructor(input, file) {
|
654
648
|
this.input = input;
|
655
649
|
this.file = file;
|
656
|
-
this.directUpload = new DirectUpload(this.file, this.url, this
|
650
|
+
this.directUpload = new DirectUpload(this.file, this.url, this);
|
657
651
|
this.dispatch("initialize");
|
658
652
|
}
|
659
653
|
start(callback) {
|
@@ -684,12 +678,6 @@ class DirectUploadController {
|
|
684
678
|
get url() {
|
685
679
|
return this.input.getAttribute("data-direct-upload-url");
|
686
680
|
}
|
687
|
-
get directUploadToken() {
|
688
|
-
return this.input.getAttribute("data-direct-upload-token");
|
689
|
-
}
|
690
|
-
get attachmentName() {
|
691
|
-
return this.input.getAttribute("data-direct-upload-attachment-name");
|
692
|
-
}
|
693
681
|
dispatch(name, detail = {}) {
|
694
682
|
detail.file = this.file;
|
695
683
|
detail.id = this.directUpload.id;
|
@@ -503,7 +503,7 @@
|
|
503
503
|
}
|
504
504
|
}
|
505
505
|
class BlobRecord {
|
506
|
-
constructor(file, checksum, url
|
506
|
+
constructor(file, checksum, url) {
|
507
507
|
this.file = file;
|
508
508
|
this.attributes = {
|
509
509
|
filename: file.name,
|
@@ -511,8 +511,6 @@
|
|
511
511
|
byte_size: file.size,
|
512
512
|
checksum: checksum
|
513
513
|
};
|
514
|
-
this.directUploadToken = directUploadToken;
|
515
|
-
this.attachmentName = attachmentName;
|
516
514
|
this.xhr = new XMLHttpRequest;
|
517
515
|
this.xhr.open("POST", url, true);
|
518
516
|
this.xhr.responseType = "json";
|
@@ -540,9 +538,7 @@
|
|
540
538
|
create(callback) {
|
541
539
|
this.callback = callback;
|
542
540
|
this.xhr.send(JSON.stringify({
|
543
|
-
blob: this.attributes
|
544
|
-
direct_upload_token: this.directUploadToken,
|
545
|
-
attachment_name: this.attachmentName
|
541
|
+
blob: this.attributes
|
546
542
|
}));
|
547
543
|
}
|
548
544
|
requestDidLoad(event) {
|
@@ -600,12 +596,10 @@
|
|
600
596
|
}
|
601
597
|
let id = 0;
|
602
598
|
class DirectUpload {
|
603
|
-
constructor(file, url,
|
599
|
+
constructor(file, url, delegate) {
|
604
600
|
this.id = ++id;
|
605
601
|
this.file = file;
|
606
602
|
this.url = url;
|
607
|
-
this.serviceName = serviceName;
|
608
|
-
this.attachmentName = attachmentName;
|
609
603
|
this.delegate = delegate;
|
610
604
|
}
|
611
605
|
create(callback) {
|
@@ -614,7 +608,7 @@
|
|
614
608
|
callback(error);
|
615
609
|
return;
|
616
610
|
}
|
617
|
-
const blob = new BlobRecord(this.file, checksum, this.url
|
611
|
+
const blob = new BlobRecord(this.file, checksum, this.url);
|
618
612
|
notify(this.delegate, "directUploadWillCreateBlobWithXHR", blob.xhr);
|
619
613
|
blob.create((error => {
|
620
614
|
if (error) {
|
@@ -643,7 +637,7 @@
|
|
643
637
|
constructor(input, file) {
|
644
638
|
this.input = input;
|
645
639
|
this.file = file;
|
646
|
-
this.directUpload = new DirectUpload(this.file, this.url, this
|
640
|
+
this.directUpload = new DirectUpload(this.file, this.url, this);
|
647
641
|
this.dispatch("initialize");
|
648
642
|
}
|
649
643
|
start(callback) {
|
@@ -674,12 +668,6 @@
|
|
674
668
|
get url() {
|
675
669
|
return this.input.getAttribute("data-direct-upload-url");
|
676
670
|
}
|
677
|
-
get directUploadToken() {
|
678
|
-
return this.input.getAttribute("data-direct-upload-token");
|
679
|
-
}
|
680
|
-
get attachmentName() {
|
681
|
-
return this.input.getAttribute("data-direct-upload-attachment-name");
|
682
|
-
}
|
683
671
|
dispatch(name, detail = {}) {
|
684
672
|
detail.file = this.file;
|
685
673
|
detail.id = this.directUpload.id;
|
@@ -5,7 +5,7 @@
|
|
5
5
|
# WARNING: All Active Storage controllers are publicly accessible by default. The
|
6
6
|
# generated URLs are hard to guess, but permanent by design. If your files
|
7
7
|
# require a higher level of protection consider implementing
|
8
|
-
# {Authenticated Controllers}[https://
|
8
|
+
# {Authenticated Controllers}[https://guides.rubyonrails.org/active_storage_overview.html#authenticated-controllers].
|
9
9
|
class ActiveStorage::Blobs::ProxyController < ActiveStorage::BaseController
|
10
10
|
include ActiveStorage::SetBlob
|
11
11
|
|
@@ -17,7 +17,7 @@ class ActiveStorage::Blobs::ProxyController < ActiveStorage::BaseController
|
|
17
17
|
response.headers["Accept-Ranges"] = "bytes"
|
18
18
|
response.headers["Content-Length"] = @blob.byte_size.to_s
|
19
19
|
|
20
|
-
send_blob_stream @blob
|
20
|
+
send_blob_stream @blob, disposition: params[:disposition]
|
21
21
|
end
|
22
22
|
end
|
23
23
|
end
|
@@ -5,7 +5,7 @@
|
|
5
5
|
# WARNING: All Active Storage controllers are publicly accessible by default. The
|
6
6
|
# generated URLs are hard to guess, but permanent by design. If your files
|
7
7
|
# require a higher level of protection consider implementing
|
8
|
-
# {Authenticated Controllers}[https://
|
8
|
+
# {Authenticated Controllers}[https://guides.rubyonrails.org/active_storage_overview.html#authenticated-controllers].
|
9
9
|
class ActiveStorage::Blobs::RedirectController < ActiveStorage::BaseController
|
10
10
|
include ActiveStorage::SetBlob
|
11
11
|
|
@@ -4,10 +4,8 @@
|
|
4
4
|
# When the client-side upload is completed, the signed_blob_id can be submitted as part of the form to reference
|
5
5
|
# the blob that was created up front.
|
6
6
|
class ActiveStorage::DirectUploadsController < ActiveStorage::BaseController
|
7
|
-
include ActiveStorage::DirectUploadToken
|
8
|
-
|
9
7
|
def create
|
10
|
-
blob = ActiveStorage::Blob.create_before_direct_upload!(**blob_args
|
8
|
+
blob = ActiveStorage::Blob.create_before_direct_upload!(**blob_args)
|
11
9
|
render json: direct_upload_json(blob)
|
12
10
|
end
|
13
11
|
|
@@ -16,10 +14,6 @@ class ActiveStorage::DirectUploadsController < ActiveStorage::BaseController
|
|
16
14
|
params.require(:blob).permit(:filename, :byte_size, :checksum, :content_type, metadata: {}).to_h.symbolize_keys
|
17
15
|
end
|
18
16
|
|
19
|
-
def verified_service_name
|
20
|
-
ActiveStorage::DirectUploadToken.verify_direct_upload_token(params[:direct_upload_token], params[:attachment_name], session)
|
21
|
-
end
|
22
|
-
|
23
17
|
def direct_upload_json(blob)
|
24
18
|
blob.as_json(root: false, methods: :signed_id).merge(direct_upload: {
|
25
19
|
url: blob.service_url_for_direct_upload,
|
@@ -5,11 +5,11 @@
|
|
5
5
|
# WARNING: All Active Storage controllers are publicly accessible by default. The
|
6
6
|
# generated URLs are hard to guess, but permanent by design. If your files
|
7
7
|
# require a higher level of protection consider implementing
|
8
|
-
# {Authenticated Controllers}[https://
|
8
|
+
# {Authenticated Controllers}[https://guides.rubyonrails.org/active_storage_overview.html#authenticated-controllers].
|
9
9
|
class ActiveStorage::Representations::ProxyController < ActiveStorage::Representations::BaseController
|
10
10
|
def show
|
11
11
|
http_cache_forever public: true do
|
12
|
-
send_blob_stream @representation.image
|
12
|
+
send_blob_stream @representation.image, disposition: params[:disposition]
|
13
13
|
end
|
14
14
|
end
|
15
15
|
end
|
@@ -5,7 +5,7 @@
|
|
5
5
|
# WARNING: All Active Storage controllers are publicly accessible by default. The
|
6
6
|
# generated URLs are hard to guess, but permanent by design. If your files
|
7
7
|
# require a higher level of protection consider implementing
|
8
|
-
# {Authenticated Controllers}[https://
|
8
|
+
# {Authenticated Controllers}[https://guides.rubyonrails.org/active_storage_overview.html#authenticated-controllers].
|
9
9
|
class ActiveStorage::Representations::RedirectController < ActiveStorage::Representations::BaseController
|
10
10
|
def show
|
11
11
|
expires_in ActiveStorage.service_urls_expire_in
|
@@ -1,19 +1,16 @@
|
|
1
1
|
import { getMetaValue } from "./helpers"
|
2
2
|
|
3
3
|
export class BlobRecord {
|
4
|
-
constructor(file, checksum, url
|
4
|
+
constructor(file, checksum, url) {
|
5
5
|
this.file = file
|
6
6
|
|
7
7
|
this.attributes = {
|
8
8
|
filename: file.name,
|
9
9
|
content_type: file.type || "application/octet-stream",
|
10
10
|
byte_size: file.size,
|
11
|
-
checksum: checksum
|
11
|
+
checksum: checksum
|
12
12
|
}
|
13
13
|
|
14
|
-
this.directUploadToken = directUploadToken
|
15
|
-
this.attachmentName = attachmentName
|
16
|
-
|
17
14
|
this.xhr = new XMLHttpRequest
|
18
15
|
this.xhr.open("POST", url, true)
|
19
16
|
this.xhr.responseType = "json"
|
@@ -46,11 +43,7 @@ export class BlobRecord {
|
|
46
43
|
|
47
44
|
create(callback) {
|
48
45
|
this.callback = callback
|
49
|
-
this.xhr.send(JSON.stringify({
|
50
|
-
blob: this.attributes,
|
51
|
-
direct_upload_token: this.directUploadToken,
|
52
|
-
attachment_name: this.attachmentName
|
53
|
-
}))
|
46
|
+
this.xhr.send(JSON.stringify({ blob: this.attributes }))
|
54
47
|
}
|
55
48
|
|
56
49
|
requestDidLoad(event) {
|
@@ -5,12 +5,10 @@ import { BlobUpload } from "./blob_upload"
|
|
5
5
|
let id = 0
|
6
6
|
|
7
7
|
export class DirectUpload {
|
8
|
-
constructor(file, url,
|
8
|
+
constructor(file, url, delegate) {
|
9
9
|
this.id = ++id
|
10
10
|
this.file = file
|
11
11
|
this.url = url
|
12
|
-
this.serviceName = serviceName
|
13
|
-
this.attachmentName = attachmentName
|
14
12
|
this.delegate = delegate
|
15
13
|
}
|
16
14
|
|
@@ -21,7 +19,7 @@ export class DirectUpload {
|
|
21
19
|
return
|
22
20
|
}
|
23
21
|
|
24
|
-
const blob = new BlobRecord(this.file, checksum, this.url
|
22
|
+
const blob = new BlobRecord(this.file, checksum, this.url)
|
25
23
|
notify(this.delegate, "directUploadWillCreateBlobWithXHR", blob.xhr)
|
26
24
|
|
27
25
|
blob.create(error => {
|
@@ -5,7 +5,7 @@ export class DirectUploadController {
|
|
5
5
|
constructor(input, file) {
|
6
6
|
this.input = input
|
7
7
|
this.file = file
|
8
|
-
this.directUpload = new DirectUpload(this.file, this.url, this
|
8
|
+
this.directUpload = new DirectUpload(this.file, this.url, this)
|
9
9
|
this.dispatch("initialize")
|
10
10
|
}
|
11
11
|
|
@@ -41,14 +41,6 @@ export class DirectUploadController {
|
|
41
41
|
return this.input.getAttribute("data-direct-upload-url")
|
42
42
|
}
|
43
43
|
|
44
|
-
get directUploadToken() {
|
45
|
-
return this.input.getAttribute("data-direct-upload-token")
|
46
|
-
}
|
47
|
-
|
48
|
-
get attachmentName() {
|
49
|
-
return this.input.getAttribute("data-direct-upload-attachment-name")
|
50
|
-
}
|
51
|
-
|
52
44
|
dispatch(name, detail = {}) {
|
53
45
|
detail.file = this.file
|
54
46
|
detail.id = this.directUpload.id
|
@@ -4,7 +4,7 @@
|
|
4
4
|
# These variants are used to create thumbnails, fixed-size avatars, or any other derivative image from the
|
5
5
|
# original.
|
6
6
|
#
|
7
|
-
# Variants rely on {ImageProcessing}[https://github.com/janko
|
7
|
+
# Variants rely on {ImageProcessing}[https://github.com/janko/image_processing] gem for the actual transformations
|
8
8
|
# of the file, so you must add <tt>gem "image_processing"</tt> to your Gemfile if you wish to use variants. By
|
9
9
|
# default, images will be processed with {ImageMagick}[http://imagemagick.org] using the
|
10
10
|
# {MiniMagick}[https://github.com/minimagick/minimagick] gem, but you can also switch to the
|
@@ -46,9 +46,9 @@
|
|
46
46
|
#
|
47
47
|
# Visit the following links for a list of available ImageProcessing commands and ImageMagick/libvips operations:
|
48
48
|
#
|
49
|
-
# * {ImageProcessing::MiniMagick}[https://github.com/janko
|
49
|
+
# * {ImageProcessing::MiniMagick}[https://github.com/janko/image_processing/blob/master/doc/minimagick.md#methods]
|
50
50
|
# * {ImageMagick reference}[https://www.imagemagick.org/script/mogrify.php]
|
51
|
-
# * {ImageProcessing::Vips}[https://github.com/janko
|
51
|
+
# * {ImageProcessing::Vips}[https://github.com/janko/image_processing/blob/master/doc/vips.md#methods]
|
52
52
|
# * {ruby-vips reference}[http://www.rubydoc.info/gems/ruby-vips/Vips/Image]
|
53
53
|
class ActiveStorage::Variant
|
54
54
|
attr_reader :blob, :variation
|
@@ -10,7 +10,7 @@ require "mini_mime"
|
|
10
10
|
#
|
11
11
|
# ActiveStorage::Variation.new(resize_to_limit: [100, 100], colourspace: "b-w", rotate: "-90", saver: { trim: true })
|
12
12
|
#
|
13
|
-
# The options map directly to {ImageProcessing}[https://github.com/janko
|
13
|
+
# The options map directly to {ImageProcessing}[https://github.com/janko/image_processing] commands.
|
14
14
|
class ActiveStorage::Variation
|
15
15
|
attr_reader :transformations
|
16
16
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
class CreateActiveStorageVariantRecords < ActiveRecord::Migration[6.0]
|
2
2
|
def change
|
3
3
|
# Use Active Record's configured type for primary key
|
4
|
-
create_table :active_storage_variant_records, id: primary_key_type do |t|
|
4
|
+
create_table :active_storage_variant_records, id: primary_key_type, if_not_exists: true do |t|
|
5
5
|
t.belongs_to :blob, null: false, index: false, type: blobs_primary_key_type
|
6
6
|
t.string :variation_digest, null: false
|
7
7
|
|
@@ -137,9 +137,11 @@ module ActiveStorage
|
|
137
137
|
end
|
138
138
|
|
139
139
|
def #{name}=(attachables)
|
140
|
+
attachables = Array(attachables).compact_blank
|
141
|
+
|
140
142
|
if ActiveStorage.replace_on_assign_to_many
|
141
143
|
attachment_changes["#{name}"] =
|
142
|
-
if
|
144
|
+
if attachables.none?
|
143
145
|
ActiveStorage::Attached::Changes::DeleteMany.new("#{name}", self)
|
144
146
|
else
|
145
147
|
ActiveStorage::Attached::Changes::CreateMany.new("#{name}", self, attachables)
|
@@ -151,7 +153,7 @@ module ActiveStorage
|
|
151
153
|
"To append new attachables to the Active Storage association, prefer using `attach`. " \
|
152
154
|
"Using association setter would result in purging the existing attached attachments and replacing them with new ones."
|
153
155
|
|
154
|
-
if
|
156
|
+
if attachables.any?
|
155
157
|
attachment_changes["#{name}"] =
|
156
158
|
ActiveStorage::Attached::Changes::CreateMany.new("#{name}", self, #{name}.blobs + attachables)
|
157
159
|
end
|
@@ -30,6 +30,7 @@ module ActiveStorage
|
|
30
30
|
config.active_storage.analyzers = [ ActiveStorage::Analyzer::ImageAnalyzer::Vips, ActiveStorage::Analyzer::ImageAnalyzer::ImageMagick, ActiveStorage::Analyzer::VideoAnalyzer, ActiveStorage::Analyzer::AudioAnalyzer ]
|
31
31
|
config.active_storage.paths = ActiveSupport::OrderedOptions.new
|
32
32
|
config.active_storage.queues = ActiveSupport::InheritableOptions.new
|
33
|
+
config.active_storage.precompile_assets = true
|
33
34
|
|
34
35
|
config.active_storage.variable_content_types = %w(
|
35
36
|
image/png
|
@@ -154,9 +155,23 @@ module ActiveStorage
|
|
154
155
|
end
|
155
156
|
end
|
156
157
|
|
158
|
+
initializer "action_view.configuration" do
|
159
|
+
config.after_initialize do |app|
|
160
|
+
ActiveSupport.on_load(:action_view) do
|
161
|
+
multiple_file_field_include_hidden = app.config.active_storage.delete(:multiple_file_field_include_hidden)
|
162
|
+
|
163
|
+
unless multiple_file_field_include_hidden.nil?
|
164
|
+
ActionView::Helpers::FormHelper.multiple_file_field_include_hidden = multiple_file_field_include_hidden
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
157
170
|
initializer "active_storage.asset" do
|
158
|
-
|
159
|
-
|
171
|
+
config.after_initialize do |app|
|
172
|
+
if app.config.respond_to?(:assets) && app.config.active_storage.precompile_assets
|
173
|
+
app.config.assets.precompile += %w( activestorage activestorage.esm )
|
174
|
+
end
|
160
175
|
end
|
161
176
|
end
|
162
177
|
|
data/lib/active_storage.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
#--
|
4
|
-
# Copyright (c) 2017-
|
4
|
+
# Copyright (c) 2017-2022 David Heinemeier Hansson, Basecamp
|
5
5
|
#
|
6
6
|
# Permission is hereby granted, free of charge, to any person obtaining
|
7
7
|
# a copy of this software and associated documentation files (the
|
@@ -41,7 +41,6 @@ module ActiveStorage
|
|
41
41
|
autoload :Service
|
42
42
|
autoload :Previewer
|
43
43
|
autoload :Analyzer
|
44
|
-
autoload :DirectUploadToken
|
45
44
|
|
46
45
|
mattr_accessor :logger
|
47
46
|
mattr_accessor :verifier
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activestorage
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 7.0.
|
4
|
+
version: 7.0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Heinemeier Hansson
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-02-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -16,56 +16,56 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - '='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 7.0.
|
19
|
+
version: 7.0.2.1
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - '='
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 7.0.
|
26
|
+
version: 7.0.2.1
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: actionpack
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - '='
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 7.0.
|
33
|
+
version: 7.0.2.1
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - '='
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 7.0.
|
40
|
+
version: 7.0.2.1
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: activejob
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - '='
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: 7.0.
|
47
|
+
version: 7.0.2.1
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - '='
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: 7.0.
|
54
|
+
version: 7.0.2.1
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: activerecord
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - '='
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: 7.0.
|
61
|
+
version: 7.0.2.1
|
62
62
|
type: :runtime
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - '='
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: 7.0.
|
68
|
+
version: 7.0.2.1
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: marcel
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -170,7 +170,6 @@ files:
|
|
170
170
|
- lib/active_storage/attached/many.rb
|
171
171
|
- lib/active_storage/attached/model.rb
|
172
172
|
- lib/active_storage/attached/one.rb
|
173
|
-
- lib/active_storage/direct_upload_token.rb
|
174
173
|
- lib/active_storage/downloader.rb
|
175
174
|
- lib/active_storage/engine.rb
|
176
175
|
- lib/active_storage/errors.rb
|
@@ -199,10 +198,10 @@ licenses:
|
|
199
198
|
- MIT
|
200
199
|
metadata:
|
201
200
|
bug_tracker_uri: https://github.com/rails/rails/issues
|
202
|
-
changelog_uri: https://github.com/rails/rails/blob/v7.0.
|
203
|
-
documentation_uri: https://api.rubyonrails.org/v7.0.
|
201
|
+
changelog_uri: https://github.com/rails/rails/blob/v7.0.2.1/activestorage/CHANGELOG.md
|
202
|
+
documentation_uri: https://api.rubyonrails.org/v7.0.2.1/
|
204
203
|
mailing_list_uri: https://discuss.rubyonrails.org/c/rubyonrails-talk
|
205
|
-
source_code_uri: https://github.com/rails/rails/tree/v7.0.
|
204
|
+
source_code_uri: https://github.com/rails/rails/tree/v7.0.2.1/activestorage
|
206
205
|
rubygems_mfa_required: 'true'
|
207
206
|
post_install_message:
|
208
207
|
rdoc_options: []
|
@@ -215,11 +214,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
215
214
|
version: 2.7.0
|
216
215
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
217
216
|
requirements:
|
218
|
-
- - "
|
217
|
+
- - ">="
|
219
218
|
- !ruby/object:Gem::Version
|
220
|
-
version:
|
219
|
+
version: '0'
|
221
220
|
requirements: []
|
222
|
-
rubygems_version: 3.2.
|
221
|
+
rubygems_version: 3.2.22
|
223
222
|
signing_key:
|
224
223
|
specification_version: 4
|
225
224
|
summary: Local and cloud file storage framework.
|
@@ -1,59 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module ActiveStorage
|
4
|
-
module DirectUploadToken
|
5
|
-
extend self
|
6
|
-
|
7
|
-
SEPARATOR = "."
|
8
|
-
DIRECT_UPLOAD_TOKEN_LENGTH = 32
|
9
|
-
|
10
|
-
def generate_direct_upload_token(attachment_name, service_name, session)
|
11
|
-
token = direct_upload_token(session, attachment_name)
|
12
|
-
encode_direct_upload_token([service_name, token].join(SEPARATOR))
|
13
|
-
end
|
14
|
-
|
15
|
-
def verify_direct_upload_token(token, attachment_name, session)
|
16
|
-
raise ActiveStorage::InvalidDirectUploadTokenError if token.nil?
|
17
|
-
|
18
|
-
service_name, *token_components = decode_token(token).split(SEPARATOR)
|
19
|
-
decoded_token = token_components.join(SEPARATOR)
|
20
|
-
|
21
|
-
return service_name if valid_direct_upload_token?(decoded_token, attachment_name, session)
|
22
|
-
|
23
|
-
raise ActiveStorage::InvalidDirectUploadTokenError
|
24
|
-
end
|
25
|
-
|
26
|
-
private
|
27
|
-
def direct_upload_token(session, attachment_name) # :doc:
|
28
|
-
direct_upload_token_hmac(session, "direct_upload##{attachment_name}")
|
29
|
-
end
|
30
|
-
|
31
|
-
def valid_direct_upload_token?(token, attachment_name, session) # :doc:
|
32
|
-
correct_token = direct_upload_token(session, attachment_name)
|
33
|
-
ActiveSupport::SecurityUtils.fixed_length_secure_compare(token, correct_token)
|
34
|
-
rescue ArgumentError
|
35
|
-
raise ActiveStorage::InvalidDirectUploadTokenError
|
36
|
-
end
|
37
|
-
|
38
|
-
def direct_upload_token_hmac(session, identifier) # :doc:
|
39
|
-
OpenSSL::HMAC.digest(
|
40
|
-
OpenSSL::Digest::SHA256.new,
|
41
|
-
real_direct_upload_token(session),
|
42
|
-
identifier
|
43
|
-
)
|
44
|
-
end
|
45
|
-
|
46
|
-
def real_direct_upload_token(session) # :doc:
|
47
|
-
session[:_direct_upload_token] ||= SecureRandom.urlsafe_base64(DIRECT_UPLOAD_TOKEN_LENGTH, padding: false)
|
48
|
-
encode_direct_upload_token(session[:_direct_upload_token])
|
49
|
-
end
|
50
|
-
|
51
|
-
def decode_token(encoded_token) # :nodoc:
|
52
|
-
Base64.urlsafe_decode64(encoded_token)
|
53
|
-
end
|
54
|
-
|
55
|
-
def encode_direct_upload_token(raw_token) # :nodoc:
|
56
|
-
Base64.urlsafe_encode64(raw_token)
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|