
Security News
/Research
Wallet-Draining npm Package Impersonates Nodemailer to Hijack Crypto Transactions
Malicious npm package impersonates Nodemailer and drains wallets by hijacking crypto transactions across multiple blockchains.
Introduction goes here.
Add solidus_content to your Gemfile:
gem 'solidus_content'
Bundle your dependencies and run the installation generator:
bundle
bin/rails generate solidus_content:install
Create an entry type for the home page:
home_entry_type = SolidusContent::EntryType.create!(
name: :home,
provider_name: :json,
options: { path: 'data/home' }
)
Create a default entry for the home page:
home = SolidusContent::Entry.create!(
entry_type: home_entry_type,
slug: :default,
)
And then write a file inside your app root under data/home/default.json
:
{"title":"Hello World!"}
Use the content inside an existing view, e.g. app/views/spree/home/index.html.erb
:
<% data = SolidusContent::Entry.data_for(:home, 'default') %>
<h1><%= data[:title] %></h1>
SolidusContent will add a default route that starts with /c/
, by adding a view
inside app/views/spree/solidus_content/
with the name of the entry type you'll
be able to render your content.
E.g. app/views/spree/solidus_content/home.html.erb
:
<h1><%= @entry.data[:title] %></h1>
Then, visit /c/home/default
or even just /c/home
(when the content slug is
"default" it can be omitted).
You can also define a custom route in your Application
routes file and use
the SolidusContent
controller to render your content from a dedicated view:
# config/routes.rb
Rails.application.routes.draw do
# Will render app/views/spree/solidus_content/home.html.erb
root to: 'spree/solidus_content#show', type: :home, id: :default
# Will render app/views/spree/solidus_content/info.html.erb
get "privacy", to: 'spree/solidus_content#show', type: :info, id: :privacy
get "legal", to: 'spree/solidus_content#show', type: :info, id: :legal
# Will render app/views/spree/solidus_content/post.html.erb
get "blog/:id", to: 'spree/solidus_content#show', type: :post
mount Spree::Core::Engine, at: '/'
end
Configure SolidusContent in an initializer:
# config/initializers/solidus_content.rb
SolidusContent.configure do |config|
# Your configuration goes here, please refer to the examples provided in the
# initializer generated by `bin/rails g solidus_content:install`
end
This is the most simple provider, its data will come directly from the entry options.
posts = SolidusContent::EntryType.create(
name: 'posts',
provider_name: 'raw',
)
entry = SolidusContent::Entry.create(
slug: '2020-03-27-hello-world',
entry_type: posts,
options: { title: "Hello World!", body: "My first post!" }
)
Will fetch the data from a JSON file within the directory specified by the
path
entry-type option and with a basename corresponding to the entry slug
.
posts = SolidusContent::EntryType.create(
name: 'posts',
provider_name: 'json',
options: { path: 'data/posts' }
)
entry = SolidusContent::Entry.create(
slug: '2020-03-27-hello-world',
entry_type: posts,
)
// [RAILS_ROOT]/data/posts/2020-03-27-hello-world.json
{"title": "Hello World!", "body": "My first post!"}
NOTE: Absolute paths are taken as they are and won't be joined to Rails.root
.
Will fetch the data from a YAML file within the directory specified by the
path
entry-type option and with a basename corresponding to the entry slug
.
If there isn't a file with the yml
extension, the yaml
extension will be tried.
posts = SolidusContent::EntryType.create(
name: 'posts',
provider_name: 'yaml',
options: { path: 'data/posts' }
)
entry = SolidusContent::Entry.create(
slug: '2020-03-27-hello-world',
entry_type: posts,
)
# [RAILS_ROOT]/data/posts/2020-03-27-hello-world.yml
title: Hello World!
body: My first post!
NOTE: Absolute paths are taken as they are and won't be joined to Rails.root
.
To retrieve the page we have to pass the page slug
to the entry options.
If the page slug is the same of the entry one, we can avoid passing the options.
posts = SolidusContent::EntryType.create(
name: 'posts',
provider_name: 'solidus_static_content'
)
entry = SolidusContent::Entry.create!(
slug: '2020-03-27-hello-world',
entry_type: posts,
options: { slug: 'XXX' } # Can be omitted if the page slug is the same of the entry
)
Be sure to have added gem "solidus_static_content"
to your Gemfile.
To fetch the data we have to create a connection with Contentful passing the
contentful_space_id
and the contentful_access_token
to the entry-type options.
Will fetch the data from Contentful passing the entry_id
entry option.
posts = SolidusContent::EntryType.create(
name: 'posts',
provider_name: 'contentful',
options: {
contentful_space_id: 'XXX',
contentful_access_token: 'XXX'
}
)
entry = SolidusContent::Entry.create!(
slug: '2020-03-27-hello-world',
entry_type: posts,
options: { entry_id: 'XXX' }
)
Be sure to have added gem "contentful"
to your Gemfile.
To fetch the data we have to create a connection with Prismic passing the
api_entry_point
to the entry-type options.
If the repository is private, you have to also pass the api_token
to the entry-type options.
Will fetch the data from Prismic passing the id
entry option.
posts = SolidusContent::EntryType.create(
name: 'posts',
provider_name: 'prismic',
options: {
api_entry_point: 'XXX',
api_token: 'XXX' # Only if the repository is private
}
)
entry = SolidusContent::Entry.create!(
slug: '2020-03-27-hello-world',
entry_type: posts,
options: { id: 'XXX' }
)
Be sure to have added gem "prismic.io"
to your Gemfile.
The Renderful provider works a bit differently from other providers because of how Renderful is configured.
The provider is not registered by default, and you'll have to register it manually by passing your Renderful instance:
# [RAILS_ROOT]/config/initializers/solidus_content.rb
require 'solidus_content/providers/renderful'
renderful = Renderful::Client.new(...)
SolidusContent.config.register_provider(
:renderful_contentful,
SolidusContent::Providers::Renderful.new(renderful),
)
Once configured, you'll be able to use it like all other providers:
posts = SolidusContent::EntryType.create(
name: 'posts',
provider_name: 'renderful_contentful',
)
entry = SolidusContent::Entry.create!(
slug: '2020-03-27-hello-world',
entry_type: posts,
options: { id: 'XXX' }
)
Unlike other providers, however, Renderful will not pass the raw entity fields to your view.
Instead, you will get a :render_in
proc that you should call with your view context. The call
will be forwarded to Renderful, which will render your content:
<%= @entry.data[:render_in].(self) %>
To register a content-provider, add a callable to the configuration under the name you prefer. The
SolidusContent.config.register_provider :json, ->(input) {
dir = Rails.root.join(input.dig(:type_options, :path))
file = dir.join(input[:slug] + '.json')
data = JSON.parse(file.read, symbolize_names: true)
input.merge(data: data)
}
The input
passed to the content-provider will have the following keys:
slug
: the slug of the content-entrytype
: the name of the content-typeprovider
: the name of the content-provideroptions
: the entry optionstype_options
: the content-type optionsThe output
of the content-provider is the input
hash augmented with the
following keys:
data
: the content itselfprovider_client
: (optional) the client of the external serviceprovider_entry
: (optional) the object retrieved from the external serviceIn both the input and output all keys should be symbolized.
Many content providers such as Contentful or Prismic can send payloads via webhooks when content changes, those can be very useful in a number of ways.
We suggest using the solidus_webhooks
extension to get the most out of solidus_content
, let's see some examples.
Add this to your Gemfile:
gem "solidus_webhooks"
In this example we setup a webhook that will create or update Contentful entries whenever they're changed or created.
# config/initializers/webhooks.rb
SolidusWebhooks.config.register_webhook_handler :contentful, -> payload {
next unless payload.dig(:sys, :Type) == "Entry"
entry_type = SolidusContent::EntryType.find_or_create_by(
name: payload.dig(:sys, :ContentType, :sys, :id),
provider_name: :raw
)
entry = entry_type.entries.find_or_initialize_by(slug: payload.dig(:sys, :id))
entry.options = payload.fetch(:fields)
}
When caching the content of app/views/spree/home/index.html.erb
as in this example:
<% cache(@entry) do %>
<h1><%= @entry.data[:title] %></h1>
<% end %>
You may want to setup a webhook that will touch the entry every time it's modified:
# config/initializers/webhooks.rb
SolidusWebhooks.config.register_webhook_handler :prismic, -> payload {
prismic_entry_types = SolidusContent::EntryType.where(provider_name: :prismic)
# Prismic doesn't give much informations about which entries have been changed,
# so we're touching them all.
SolidusContent::Entry.where(entry_type: prismic_entry_types).touch_all
}
NOTE: touch_all
was introduced in Rails 6, for earlier versions use find_each(&:touch)
.
First bundle your dependencies, then run bin/rake
. bin/rake
will default to building the dummy
app if it does not exist, then it will run specs. The dummy app can be regenerated by using
bin/rake extension:test_app
.
bundle
bin/rake
To run Rubocop static code analysis run
bundle exec rubocop
When testing your application's integration with this extension you may use its factories. Simply add this require statement to your spec_helper:
require 'solidus_content/factories'
To run this extension in a sandboxed Solidus application, you can run bin/sandbox
. The path for
the sandbox app is ./sandbox
and bin/rails
will forward any Rails commands to
sandbox/bin/rails
.
Here's an example:
$ bin/rails server
=> Booting Puma
=> Rails 6.0.2.1 application starting in development
* Listening on tcp://127.0.0.1:3000
Use Ctrl-C to stop
Your new extension version can be released using gem-release
like this:
bundle exec gem bump -v VERSION --tag --push --remote upstream && gem release
Copyright (c) 2020 Nebulab, released under the New BSD License
FAQs
Unknown package
We found that solidus_content demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 2 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.
Security News
/Research
Malicious npm package impersonates Nodemailer and drains wallets by hijacking crypto transactions across multiple blockchains.
Security News
This episode explores the hard problem of reachability analysis, from static analysis limits to handling dynamic languages and massive dependency trees.
Security News
/Research
Malicious Nx npm versions stole secrets and wallet info using AI CLI tools; Socket’s AI scanner detected the supply chain attack and flagged the malware.