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.
Drink Google Maps Services with ease! :tropical_drink: :earth_americas:
This gem aims at progressively covering a fair amount of those widely-used services that are part of the Google Maps Platform, such as: Geocoding, Time Zone, Directions, etc. with some key ideas:
GoogleMapsJuice
currently covers:
Contributors are welcome!
Add this line to your application's Gemfile:
gem 'google_maps_juice'
And then execute:
$ bundle
Or install it yourself as:
$ gem install google_maps_juice
You can set your Google API key with the following one-liner:
GoogleMapsJuice.configure { |c| c.api_key = 'my-api-key' }`
In a Rails application, that would typically go in an initializer.
If you need to use multiple API keys, you have two options:
api_key
named param to the endpoint class method, e.g.GoogleMapsJuice::Geocoding.geocode(params, api_key: 'my-api-key')
GoogleMapsJuice::Client
instance(s) and use it to create your endpoint object(s), e.g.client = GoogleMapsJuice::Client.new(api_key: 'my-api-key')
geocoding = GoogleMapsJuice::Geocoding.new(client)
response = geocoding.geocode(params)
This is especially useful in some "hybrid" scenario, where an API key is shared by a group of requests, but another group uses a different key: a client
object would then be instantiated and reused for each group.
If Google servers respond with a non-successful HTTP status code, i.e. 4xx
or 5xx
, a GoogleMapsJuice::ResponseError
is raised with a message of the form 'HTTP 503 - Error details as returned by the server'
.
API errors are also handled, based on the status
attribute of Google's JSON response, and the optional error_message
attribute.
GoogleMapsJuice::ZeroResults
is raised when status
is 'ZERO_RESULTS'
GoogleMapsJuice::ApiLimitError
is raised when status
is 'OVER_DAILY_LIMIT'
or 'OVER_QUERY_LIMIT'
GoogleMapsJuice::ResponseError
is raised when status
is not OK
with a message of the form API <status> - <error_message>
The simplest geocoding requests accept an address:
response = GoogleMapsJuice::Geocoding.geocode(address: '8955 Lantana Rd, Lake Worth, FL 33467, USA')
Supported params are the ones accepted by Google's endpoint: address
, components
, bounds
, language
, region
; at least one between address
and components
is required. Learn more here. GoogleMapsJuice
will raise an ArgumentError
if some unsupported param is passed, or when none of the required params are passed.
Motivation
For best geocoding results, the address
param should be formatted according to the local language. This is often a hard task for an application that needs to geocode addresses stored as separate fields. Luckily, Google offers the components
param which accepts individual address fields; however, it's annoying to build it and it's not fault tolerant. For example, an error on postal_code
makes geocoding of a whole address fail.
Purpose of i_geocode
method is twofold:
components
paramHere an example call with all supported params:
response = GoogleMapsJuice::Geocoding.i_geocode(
{
address: '8955 Lantana Rd',
locality: 'Lake Worth',
administrative_area: 'FL',
postal_code: '33467',
country: 'US'
}, sleep_before_retry: 0.15
)
Accepted params:
address
and country
is requiredlocality
, administrative_area
, postal_code
and country
expect the same content as described in Component Filteringaddress
can also include more info than street number and name, as long as they do not contrast with other params passedsleep_before_retry
param sets seconds between geocoding attempts (see below); defaults to zero.GoogleMapsJuice
will raise an ArgumentError
if some unsupported param is passed, or when none of the required params are passed.How it works
On its 1st attempt, i_geocode
sends all received params to Google's endpoint, properly formatted. If a GoogleMapsJuice::ZeroResults
is raised, it removes a param and retries until no error is raised. Params are removed in the following order:
postal_code
address
locality
administrative_area
As a consequence:
i_geocode
will send 1 request to Google APIi_geocode
will send 4 requests to Google APIBoth geocode
and i_geocode
methods return a GoogleMapsJuice::Geocoding::Response
. It's a Hash
representation of Google's JSON response. However, it also provides many useful methods:
latitude
, longitude
: geographic coordinates as float
numbers
street_number
, route
, locality
, postal_code
, administrative_area_level_1
, country
: all of these methods return a Hash
with 2 keys: 'short_name'
and 'long_name'
partial_match?
: boolean, true
if some param (of the last geocoding attempt) partially matched
precision
: can be one of: 'street_number'
, 'route'
, 'locality'
, 'postal_code'
, 'administrative_area_level_1'
, 'country'
and represents the most-specific matching component
Google's Time Zone API returns the time zone of a given geographic location; it also accepts a timestamp, in order to determine whether DST should be applied or not.
GoogleMapsJuice provides the GoogleMapsJuice::Timezone.by_location
method. Compared to Google's raw API request, it provides simpler params and some validations, in order to avoid sending requests when they would fail for sure (and then save money!) - to learn more see spec/unit/timezone_spec.rb
.
Accepted params:
latitude
and longitude
are mandatorytimestamp
is optional and defaults to Time.now
language
is optionalThe by_location
method returns a GoogleMapsJuice::Timezone::Response
. It's a Hash
representation of Google's JSON response. However, it also provides a few useful methods:
timezone_id
: unique name as defined in IANA Time Zone Database
timezone_name
: the long form name of the time zone
raw_offset
: the offset from UTC in seconds
dst_offset
: the offset for daylight-savings time in seconds
Google's Directions API returns the possible routes of given origin and destination geographic locations; Google's API accepts address, textual latitude/longitude value, or place ID of which you wish to calculate directions. Currently this gem implements only latitude/longitude mode.
GoogleMapsJuice
will raise an ArgumentError
if some unsupported param is passed, or when none of the required params are passed.
response = GoogleMapsJuice::Directions.find(origin: '41.8892732,12.4921921', destination: '41.9016488,12.4583003')
Compared to Google's raw API request, it provides validation of both origin and destination, in order to avoid sending requests when they would fail for sure - to learn more see spec/unit/directions_spec.rb
.
Accepted params:
origin
and destination
are mandatoryorigin
is composed by latitude
and longitude
, comma separated float valuesdestination
same format as origin
The find
method returns a GoogleMapsJuice::Directions::Response
. It's a Hash
representation of Google's JSON response. However, it also provides a few useful methods:
results
: the Hash
raw result
routes
: an Array
of GoogleMapsJuice::Directions::Response::Route
objects
first
: the first Route
of the routes
List
As described in Google's Directions API, the response contains all possible routes. Each route has some attributes and one or more legs, wich in turn have one or more steps.
If no waypoints are passed, the route response will contain a single leg. Since GoogleMapsJuice::Directions
doesn't handles waypoints yet, only the first leg is considered for each route.
The GoogleMapsJuice::Directions::Response::Route
is a representation of a response route and provides methods to access all route's attributes:
summary
: a brief description of the route
legs
: all legs of the route, generally a single one
steps
: all steps of the first route's leg
duration
: time duration of the first route's leg
distance
: distance between origin and destination of first route's leg
start_location
: latitude
/longitude
of the origin first route's leg
end_location
: latitude
/longitude
of the destination first route's leg
start_address
: address of the origin first route's leg
end_address
: address of the destination first route's leg
After checking out the repo, run bin/setup
to install dependencies. Create a .env
file and save your Google API key there; if you want to use a different key for testing, put it in .env.test
and it will override the one in .env
.
Run rake spec
to run the tests. You can also run bin/console
for an interactive prompt that will allow you to experiment.
To install this gem onto your local machine, run bundle exec rake install
. To release a new version, update the version number in version.rb
, and then run bundle exec rake release
, which will create a git tag for the version, push git commits and tags and push the .gem
file to rubygems.org.
All endpoints must be subclasses of GoogleMapsJuice::Endpoint
; methods that implement "standard" Google API calls have a common structure, described by the invoke
method in the SomeEndpoint
test class in spec/unit/endpoint_spec.rb
.
All new endpoints' methods must return subclasses of GoogleMapsJuice::Endpoint::Response
as their response objects, since it contains methods needed for error handling.
Bug reports and pull requests are welcome on GitHub at https://github.com/algonauti/google_maps_juice.
The gem is available as open source under the terms of the MIT License.
FAQs
Unknown package
We found that google_maps_juice demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer 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.