mirror of
https://github.com/cydrobolt/polr.git
synced 2024-11-09 19:52:28 +01:00
Merge branch 'master' into 157-replace-px-with-em
This commit is contained in:
commit
bed2488fd1
@ -16,7 +16,7 @@ CACHE_DRIVER=file
|
|||||||
SESSION_DRIVER=file
|
SESSION_DRIVER=file
|
||||||
QUEUE_DRIVER=file
|
QUEUE_DRIVER=file
|
||||||
|
|
||||||
VERSION=2.2.0
|
VERSION=2.3.0
|
||||||
VERSION_RELMONTH=May
|
VERSION_RELMONTH=Jan
|
||||||
VERSION_RELDAY=6
|
VERSION_RELDAY=28
|
||||||
VERSION_RELYEAR=2017
|
VERSION_RELYEAR=2020
|
||||||
|
@ -66,13 +66,13 @@ class LinkFactory {
|
|||||||
// has custom ending
|
// has custom ending
|
||||||
$ending_conforms = LinkHelper::validateEnding($custom_ending);
|
$ending_conforms = LinkHelper::validateEnding($custom_ending);
|
||||||
if (!$ending_conforms) {
|
if (!$ending_conforms) {
|
||||||
throw new \Exception('Sorry, but custom endings
|
throw new \Exception('Custom endings
|
||||||
can only contain alphanumeric characters, hyphens, and underscores.');
|
can only contain alphanumeric characters, hyphens, and underscores.');
|
||||||
}
|
}
|
||||||
|
|
||||||
$ending_in_use = LinkHelper::linkExists($custom_ending);
|
$ending_in_use = LinkHelper::linkExists($custom_ending);
|
||||||
if ($ending_in_use) {
|
if ($ending_in_use) {
|
||||||
throw new \Exception('Sorry, but this URL ending is already in use.');
|
throw new \Exception('This URL ending is already in use.');
|
||||||
}
|
}
|
||||||
|
|
||||||
$link_ending = $custom_ending;
|
$link_ending = $custom_ending;
|
||||||
@ -97,7 +97,6 @@ class LinkFactory {
|
|||||||
$link->is_api = $is_api;
|
$link->is_api = $is_api;
|
||||||
|
|
||||||
if ($creator) {
|
if ($creator) {
|
||||||
// if user is logged in, save user as creator
|
|
||||||
$link->creator = $creator;
|
$link->creator = $creator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,6 +61,7 @@ class StatsHelper {
|
|||||||
->select(DB::raw("country AS label, count(*) AS clicks"))
|
->select(DB::raw("country AS label, count(*) AS clicks"))
|
||||||
->groupBy('country')
|
->groupBy('country')
|
||||||
->orderBy('clicks', 'desc')
|
->orderBy('clicks', 'desc')
|
||||||
|
->whereNotNull('country')
|
||||||
->get();
|
->get();
|
||||||
|
|
||||||
return $stats;
|
return $stats;
|
||||||
|
@ -7,12 +7,22 @@ use App\Helpers\LinkHelper;
|
|||||||
use App\Exceptions\Api\ApiException;
|
use App\Exceptions\Api\ApiException;
|
||||||
|
|
||||||
class ApiLinkController extends ApiController {
|
class ApiLinkController extends ApiController {
|
||||||
|
protected function getShortenedLink($long_url, $is_secret, $custom_ending, $link_ip, $username, $response_type) {
|
||||||
|
try {
|
||||||
|
$formatted_link = LinkFactory::createLink(
|
||||||
|
$long_url, $is_secret, $custom_ending, $link_ip, $username, false, true);
|
||||||
|
}
|
||||||
|
catch (\Exception $e) {
|
||||||
|
throw new ApiException('CREATION_ERROR', $e->getMessage(), 400, $response_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $formatted_link;
|
||||||
|
}
|
||||||
|
|
||||||
public function shortenLink(Request $request) {
|
public function shortenLink(Request $request) {
|
||||||
$response_type = $request->input('response_type');
|
$response_type = $request->input('response_type');
|
||||||
$user = $request->user;
|
$user = $request->user;
|
||||||
|
|
||||||
// Validate parameters
|
|
||||||
// Encode spaces as %20 to avoid validator conflicts
|
|
||||||
$validator = \Validator::make(array_merge([
|
$validator = \Validator::make(array_merge([
|
||||||
'url' => str_replace(' ', '%20', $request->input('url'))
|
'url' => str_replace(' ', '%20', $request->input('url'))
|
||||||
], $request->except('url')), [
|
], $request->except('url')), [
|
||||||
@ -23,22 +33,71 @@ class ApiLinkController extends ApiController {
|
|||||||
throw new ApiException('MISSING_PARAMETERS', 'Invalid or missing parameters.', 400, $response_type);
|
throw new ApiException('MISSING_PARAMETERS', 'Invalid or missing parameters.', 400, $response_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
$long_url = $request->input('url'); // * required
|
$formatted_link = $this->getShortenedLink(
|
||||||
$is_secret = ($request->input('is_secret') == 'true' ? true : false);
|
$request->input('url'),
|
||||||
|
($request->input('is_secret') == 'true' ? true : false),
|
||||||
$link_ip = $request->ip();
|
$request->input('custom_ending'),
|
||||||
$custom_ending = $request->input('custom_ending');
|
$request->ip(),
|
||||||
|
$user->username,
|
||||||
try {
|
$response_type
|
||||||
$formatted_link = LinkFactory::createLink($long_url, $is_secret, $custom_ending, $link_ip, $user->username, false, true);
|
);
|
||||||
}
|
|
||||||
catch (\Exception $e) {
|
|
||||||
throw new ApiException('CREATION_ERROR', $e->getMessage(), 400, $response_type);
|
|
||||||
}
|
|
||||||
|
|
||||||
return self::encodeResponse($formatted_link, 'shorten', $response_type);
|
return self::encodeResponse($formatted_link, 'shorten', $response_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function shortenLinksBulk(Request $request) {
|
||||||
|
$response_type = $request->input('response_type', 'json');
|
||||||
|
$request_data = $request->input('data');
|
||||||
|
|
||||||
|
$user = $request->user;
|
||||||
|
$link_ip = $request->ip();
|
||||||
|
$username = $user->username;
|
||||||
|
|
||||||
|
if ($response_type != 'json') {
|
||||||
|
throw new ApiException('JSON_ONLY', 'Only JSON-encoded responses are available for this endpoint.', 401, $response_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
$links_array_raw_json = json_decode($request_data, true);
|
||||||
|
|
||||||
|
if ($links_array_raw_json === null) {
|
||||||
|
throw new ApiException('INVALID_PARAMETERS', 'Invalid JSON.', 400, $response_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
$links_array = $links_array_raw_json['links'];
|
||||||
|
|
||||||
|
foreach ($links_array as $link) {
|
||||||
|
$validator = \Validator::make($link, [
|
||||||
|
'url' => 'required|url'
|
||||||
|
]);
|
||||||
|
|
||||||
|
if ($validator->fails()) {
|
||||||
|
throw new ApiException('MISSING_PARAMETERS', 'Invalid or missing parameters.', 400, $response_type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$formatted_links = [];
|
||||||
|
|
||||||
|
foreach ($links_array as $link) {
|
||||||
|
$formatted_link = $this->getShortenedLink(
|
||||||
|
$link['url'],
|
||||||
|
(array_get($link, 'is_secret') == 'true' ? true : false),
|
||||||
|
array_get($link, 'custom_ending'),
|
||||||
|
$link_ip,
|
||||||
|
$username,
|
||||||
|
$response_type
|
||||||
|
);
|
||||||
|
|
||||||
|
$formatted_links[] = [
|
||||||
|
'long_url' => $link['url'],
|
||||||
|
'short_url' => $formatted_link
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return self::encodeResponse([
|
||||||
|
'shortened_links' => $formatted_links
|
||||||
|
], 'shorten_bulk', 'json');
|
||||||
|
}
|
||||||
|
|
||||||
public function lookupLink(Request $request) {
|
public function lookupLink(Request $request) {
|
||||||
$user = $request->user;
|
$user = $request->user;
|
||||||
$response_type = $request->input('response_type');
|
$response_type = $request->input('response_type');
|
||||||
|
@ -3,6 +3,7 @@ namespace App\Http\Controllers;
|
|||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Http\Redirect;
|
use Illuminate\Http\Redirect;
|
||||||
use Illuminate\Support\Facades\Artisan;
|
use Illuminate\Support\Facades\Artisan;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
use App\Helpers\CryptoHelper;
|
use App\Helpers\CryptoHelper;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
@ -106,6 +107,8 @@ class SetupController extends Controller {
|
|||||||
$polr_recaptcha_site_key = $request->input('setting:recaptcha_site_key');
|
$polr_recaptcha_site_key = $request->input('setting:recaptcha_site_key');
|
||||||
$polr_recaptcha_secret_key = $request->input('setting:recaptcha_secret_key');
|
$polr_recaptcha_secret_key = $request->input('setting:recaptcha_secret_key');
|
||||||
|
|
||||||
|
$maxmind_license_key = $request->input('maxmind:license_key');
|
||||||
|
|
||||||
$acct_username = $request->input('acct:username');
|
$acct_username = $request->input('acct:username');
|
||||||
$acct_email = $request->input('acct:email');
|
$acct_email = $request->input('acct:email');
|
||||||
$acct_password = $request->input('acct:password');
|
$acct_password = $request->input('acct:password');
|
||||||
@ -148,6 +151,7 @@ class SetupController extends Controller {
|
|||||||
'APP_STYLESHEET' => $app_stylesheet,
|
'APP_STYLESHEET' => $app_stylesheet,
|
||||||
'POLR_GENERATED_AT' => $date_today,
|
'POLR_GENERATED_AT' => $date_today,
|
||||||
'POLR_SETUP_RAN' => $polr_setup_ran,
|
'POLR_SETUP_RAN' => $polr_setup_ran,
|
||||||
|
'MAXMIND_LICENSE_KEY' => $maxmind_license_key,
|
||||||
|
|
||||||
'DB_HOST' => $db_host,
|
'DB_HOST' => $db_host,
|
||||||
'DB_PORT' => $db_port,
|
'DB_PORT' => $db_port,
|
||||||
@ -215,8 +219,8 @@ class SetupController extends Controller {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static function finishSetup(Request $request) {
|
public static function finishSetup(Request $request) {
|
||||||
// get data from cookie, decode JSON
|
|
||||||
if (!isset($_COOKIE['setup_arguments'])) {
|
if (!isset($_COOKIE['setup_arguments'])) {
|
||||||
|
// Abort if setup arguments are missing.
|
||||||
abort(404);
|
abort(404);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -226,12 +230,19 @@ class SetupController extends Controller {
|
|||||||
// unset cookie
|
// unset cookie
|
||||||
setcookie('setup_arguments', '', time()-3600);
|
setcookie('setup_arguments', '', time()-3600);
|
||||||
|
|
||||||
$transaction_authorised = env('TMP_SETUP_AUTH_KEY') == $setup_finish_args->setup_auth_key;
|
$transaction_authorised = env('TMP_SETUP_AUTH_KEY') === $setup_finish_args->setup_auth_key;
|
||||||
|
|
||||||
if ($transaction_authorised != true) {
|
if ($transaction_authorised != true) {
|
||||||
abort(403, 'Transaction unauthorised.');
|
abort(403, 'Transaction unauthorised.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$usersTableExists = Schema::hasTable('users');
|
||||||
|
|
||||||
|
if ($usersTableExists) {
|
||||||
|
// If the users table exists, then the setup process may have already been completed before.
|
||||||
|
abort(403, 'Setup has been completed already.');
|
||||||
|
}
|
||||||
|
|
||||||
$database_created = self::createDatabase();
|
$database_created = self::createDatabase();
|
||||||
if (!$database_created) {
|
if (!$database_created) {
|
||||||
return redirect(route('setup'))->with('error', 'Could not create database. Perhaps your credentials were incorrect?');
|
return redirect(route('setup'))->with('error', 'Could not create database. Perhaps your credentials were incorrect?');
|
||||||
@ -240,7 +251,7 @@ class SetupController extends Controller {
|
|||||||
if (env('SETTING_ADV_ANALYTICS')) {
|
if (env('SETTING_ADV_ANALYTICS')) {
|
||||||
$geoip_db_created = self::updateGeoIP();
|
$geoip_db_created = self::updateGeoIP();
|
||||||
if (!$geoip_db_created) {
|
if (!$geoip_db_created) {
|
||||||
return redirect(route('setup'))->with('error', 'Could not fetch GeoIP database for advanced analytics. Perhaps your server is not connected to the internet?');
|
return redirect(route('setup'))->with('error', 'Could not fetch GeoIP database for advanced analytics. Perhaps your server is not connected to the internet or your MAXMIND_LICENSE_KEY is incorrect?');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,6 +66,7 @@ $app->group(['prefix' => '/api/v2', 'namespace' => 'App\Http\Controllers\Api', '
|
|||||||
/* API shorten endpoints */
|
/* API shorten endpoints */
|
||||||
$app->post('action/shorten', ['as' => 'api_shorten_url', 'uses' => 'ApiLinkController@shortenLink']);
|
$app->post('action/shorten', ['as' => 'api_shorten_url', 'uses' => 'ApiLinkController@shortenLink']);
|
||||||
$app->get('action/shorten', ['as' => 'api_shorten_url', 'uses' => 'ApiLinkController@shortenLink']);
|
$app->get('action/shorten', ['as' => 'api_shorten_url', 'uses' => 'ApiLinkController@shortenLink']);
|
||||||
|
$app->post('action/shorten_bulk', ['as' => 'api_shorten_url_bulk', 'uses' => 'ApiLinkController@shortenLinksBulk']);
|
||||||
|
|
||||||
/* API lookup endpoints */
|
/* API lookup endpoints */
|
||||||
$app->post('action/lookup', ['as' => 'api_lookup_url', 'uses' => 'ApiLinkController@lookupLink']);
|
$app->post('action/lookup', ['as' => 'api_lookup_url', 'uses' => 'ApiLinkController@lookupLink']);
|
||||||
|
@ -14,8 +14,9 @@
|
|||||||
"torann/geoip": "^1.0",
|
"torann/geoip": "^1.0",
|
||||||
"geoip2/geoip2": "^2.4",
|
"geoip2/geoip2": "^2.4",
|
||||||
"nesbot/carbon": "^1.22",
|
"nesbot/carbon": "^1.22",
|
||||||
"doctrine/dbal": "^2.5",
|
"doctrine/dbal": "2.5.11",
|
||||||
"google/recaptcha": "~1.1"
|
"google/recaptcha": "~1.1",
|
||||||
|
"symfony/http-foundation": "2.7.51"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"fzaninotto/faker": "~1.0",
|
"fzaninotto/faker": "~1.0",
|
||||||
|
2323
composer.lock
generated
2323
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@ -54,7 +54,7 @@ return [
|
|||||||
'maxmind_database' => [
|
'maxmind_database' => [
|
||||||
'class' => \Torann\GeoIP\Services\MaxMindDatabase::class,
|
'class' => \Torann\GeoIP\Services\MaxMindDatabase::class,
|
||||||
'database_path' => storage_path('app/geoip.mmdb'),
|
'database_path' => storage_path('app/geoip.mmdb'),
|
||||||
'update_url' => 'https://geolite.maxmind.com/download/geoip/database/GeoLite2-City.mmdb.gz',
|
'update_url' => sprintf('https://download.maxmind.com/app/geoip_download?edition_id=GeoLite2-City&license_key=%s&suffix=tar.gz', env('MAXMIND_LICENSE_KEY')),
|
||||||
'locales' => ['en'],
|
'locales' => ['en'],
|
||||||
],
|
],
|
||||||
|
|
||||||
@ -126,18 +126,18 @@ return [
|
|||||||
|
|
||||||
'default_location' => [
|
'default_location' => [
|
||||||
'ip' => '127.0.0.0',
|
'ip' => '127.0.0.0',
|
||||||
'iso_code' => 'US',
|
'iso_code' => null,
|
||||||
'country' => 'United States',
|
'country' => null,
|
||||||
'city' => 'New Haven',
|
'city' => null,
|
||||||
'state' => 'CT',
|
'state' => null,
|
||||||
'state_name' => 'Connecticut',
|
'state_name' => null,
|
||||||
'postal_code' => '06510',
|
'postal_code' => null,
|
||||||
'lat' => 41.31,
|
'lat' => 0,
|
||||||
'lon' => -72.92,
|
'lon' => 0,
|
||||||
'timezone' => 'America/New_York',
|
'timezone' => 'UTC',
|
||||||
'continent' => 'NA',
|
'continent' => null,
|
||||||
'default' => true,
|
'default' => true,
|
||||||
'currency' => 'USD',
|
'currency' => null,
|
||||||
],
|
],
|
||||||
|
|
||||||
];
|
];
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
-----------------------------
|
-----------------------------
|
||||||
|
|
||||||
## API keys
|
## API keys
|
||||||
To authenticate a user to Polr, you will need to provide an API key along with
|
To authenticate a user to Polr, you *must* provide an API key along with
|
||||||
each request to the Polr API, as a GET or POST parameter. (e.g `?key=API_KEY_HERE`)
|
each request to Polr API endpoints, as a GET or POST parameter. (e.g `?key=API_KEY_HERE`)
|
||||||
|
|
||||||
## Assigning an API key
|
## Assigning an API key
|
||||||
To assign an API key, log on from an administrator account, head over to the "Admin"
|
To assign an API key, log on from an administrator account, head over to the "Admin"
|
||||||
@ -26,11 +26,9 @@ See [API endpoints](#api-endpoints) for more information on the actions.
|
|||||||
|
|
||||||
## Response Type
|
## Response Type
|
||||||
The Polr API will reply in `plain_text` or `json`. The response type can be
|
The Polr API will reply in `plain_text` or `json`. The response type can be
|
||||||
set by providing the `response_type` argument to the request. If not provided,
|
set by providing the `response_type` argument to the request. If this argument is not provided,
|
||||||
the response type will default to `plain_text`.
|
the response type will default to either `plain_text` or `json` depending
|
||||||
|
on the endpoint.
|
||||||
Data endpoints will only return JSON-formatted data and will default to `json` if no
|
|
||||||
`response_type` is provided.
|
|
||||||
|
|
||||||
Example `json` responses:
|
Example `json` responses:
|
||||||
```
|
```
|
||||||
@ -84,7 +82,61 @@ Response:
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Remember that the `url` argument must be URL encoded.
|
The `url` argument must be URL encoded.
|
||||||
|
|
||||||
|
### /api/v2/action/shorten_bulk
|
||||||
|
|
||||||
|
_`POST` only_
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
- `data`: a string containing a JSON-encoded object with an array of links
|
||||||
|
|
||||||
|
Example `data` argument:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"links": [
|
||||||
|
{
|
||||||
|
"url": "https://polrproject.org/"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://youtube.com",
|
||||||
|
"is_secret": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://github.com/cydrobolt/polr",
|
||||||
|
"custom_ending": "polrgithub"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Response: A JSON-encoded object with a list of shortened links.
|
||||||
|
|
||||||
|
Example response:
|
||||||
|
```
|
||||||
|
{
|
||||||
|
"action": "shorten_bulk",
|
||||||
|
"result": {
|
||||||
|
"shortened_links": [
|
||||||
|
{
|
||||||
|
"long_url": "https://polrproject.org/",
|
||||||
|
"short_url": "http://demo.polr.me/81"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"long_url": "https://youtube.com",
|
||||||
|
"short_url": "http://demo.polr.me/84/b496"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"long_url": "https://github.com/cydrobolt/polr",
|
||||||
|
"short_url": "http://demo.polr.me/polrgithub"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### /api/v2/action/lookup
|
### /api/v2/action/lookup
|
||||||
The `lookup` action takes a single argument: `url_ending`. This is the URL to
|
The `lookup` action takes a single argument: `url_ending`. This is the URL to
|
||||||
|
@ -8,6 +8,8 @@ it to `true` in `.env`
|
|||||||
|
|
||||||
`MISSING_PARAMETERS`: Invalid or missing parameters.
|
`MISSING_PARAMETERS`: Invalid or missing parameters.
|
||||||
|
|
||||||
|
`INVALID_PARAMETERS`: Invalid parameters.
|
||||||
|
|
||||||
`NOT_FOUND`: Object not found.
|
`NOT_FOUND`: Object not found.
|
||||||
|
|
||||||
`ACCESS_DENIED`: User is not authorized to access the object.
|
`ACCESS_DENIED`: User is not authorized to access the object.
|
||||||
|
@ -23,7 +23,7 @@ you may be interested in looking at a [legacy 1.x release](https://github.com/cy
|
|||||||
- JSON PHP Extension
|
- JSON PHP Extension
|
||||||
- PHP curl extension
|
- PHP curl extension
|
||||||
|
|
||||||
## Downloading the source code
|
## Download the source code
|
||||||
|
|
||||||
If you would like to download a stable version of Polr, you may check out [the releases page](https://github.com/cydrobolt/polr/releases).
|
If you would like to download a stable version of Polr, you may check out [the releases page](https://github.com/cydrobolt/polr/releases).
|
||||||
|
|
||||||
@ -49,7 +49,7 @@ $ chown -R apache polr
|
|||||||
$ chcon -R -t httpd_sys_rw_content_t polr/storage polr/.env
|
$ chcon -R -t httpd_sys_rw_content_t polr/storage polr/.env
|
||||||
```
|
```
|
||||||
|
|
||||||
## Installing using `composer`
|
## Install `composer` dependencies
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# download composer package
|
# download composer package
|
||||||
@ -177,7 +177,7 @@ server {
|
|||||||
To run Polr on another HTTP server or on shared hosting, you will need to set the home
|
To run Polr on another HTTP server or on shared hosting, you will need to set the home
|
||||||
directory to `/PATH_TO_POLR/public`, not the root Polr folder.
|
directory to `/PATH_TO_POLR/public`, not the root Polr folder.
|
||||||
|
|
||||||
## Creating the database
|
## Create the database
|
||||||
|
|
||||||
### MySQL
|
### MySQL
|
||||||
|
|
||||||
|
20
docs/user-guide/maxmind-license.md
Normal file
20
docs/user-guide/maxmind-license.md
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
# Obtaining a MaxMind GeoIP License Key
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
If you would like to use "advanced analytics" in order to get more insights on your users, you must input a MaxMind GeoIP license key during the setup process or add it later to your configuration file (`.env`).
|
||||||
|
|
||||||
|
To obtain a license key, create an account on [MaxMind's website](https://www.maxmind.com/en/geolite2/signup). After you create your account and confirm your email, go to your [MaxMind account page](https://www.maxmind.com/en/accounts/current/license-key) to generate a license key for use with Polr. If you are asked whether your license key will be used for "GeoIP Update", answer no.
|
||||||
|
|
||||||
|
Copy your newly generated license key and input it into Polr.
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### I'm having trouble running `php artisan geoip:update`, and I'm using an older version of Polr
|
||||||
|
|
||||||
|
If you are on an older version of Polr, your installation may be updated. Update Polr by running `git pull` and then add a new entry to your `.env` configuration file:
|
||||||
|
|
||||||
|
```
|
||||||
|
MAXMIND_LICENSE_KEY="LICENSE_KEY_GOES_HERE"
|
||||||
|
```
|
||||||
|
|
||||||
|
Then, run `php artisan config:cache` and `php artisan geoip:update` again.
|
@ -4,6 +4,7 @@ pages:
|
|||||||
- User Guide:
|
- User Guide:
|
||||||
- 'Installation': 'user-guide/installation.md'
|
- 'Installation': 'user-guide/installation.md'
|
||||||
- 'Upgrading': 'user-guide/upgrading.md'
|
- 'Upgrading': 'user-guide/upgrading.md'
|
||||||
|
- 'Obtaining a MaxMind License Key': 'user-guide/maxmind-license.md'
|
||||||
- 'Troubleshooting': 'user-guide/troubleshooting.md'
|
- 'Troubleshooting': 'user-guide/troubleshooting.md'
|
||||||
- Developer Guide:
|
- Developer Guide:
|
||||||
- 'Libraries': 'developer-guide/libraries.md'
|
- 'Libraries': 'developer-guide/libraries.md'
|
||||||
|
@ -267,14 +267,16 @@ polr.controller('AdminCtrl', function($scope, $compile, $timeout) {
|
|||||||
|
|
||||||
// Delete user
|
// Delete user
|
||||||
$scope.deleteUser = function($event, user_id) {
|
$scope.deleteUser = function($event, user_id) {
|
||||||
var el = $($event.target);
|
var delete_user_confirm = window.confirm('Are you sure you would like to delete this user?');
|
||||||
|
|
||||||
apiCall('admin/delete_user', {
|
if (delete_user_confirm) {
|
||||||
'user_id': user_id,
|
apiCall('admin/delete_user', {
|
||||||
}, function(new_status) {
|
'user_id': user_id,
|
||||||
toastr.success('User successfully deleted.', 'Success');
|
}, function(new_status) {
|
||||||
$scope.reloadUserTables();
|
toastr.success('User successfully deleted.', 'Success');
|
||||||
});
|
$scope.reloadUserTables();
|
||||||
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.changeUserRole = function(role, user_id) {
|
$scope.changeUserRole = function(role, user_id) {
|
||||||
@ -308,14 +310,16 @@ polr.controller('AdminCtrl', function($scope, $compile, $timeout) {
|
|||||||
|
|
||||||
// Delete link
|
// Delete link
|
||||||
$scope.deleteLink = function($event, link_ending) {
|
$scope.deleteLink = function($event, link_ending) {
|
||||||
var el = $($event.target);
|
var delete_link_confirm = window.confirm('Are you sure you would like to delete this link?');
|
||||||
|
|
||||||
apiCall('admin/delete_link', {
|
if (delete_link_confirm) {
|
||||||
'link_ending': link_ending,
|
apiCall('admin/delete_link', {
|
||||||
}, function(new_status) {
|
'link_ending': link_ending,
|
||||||
toastr.success('Link successfully deleted.', 'Success');
|
}, function(new_status) {
|
||||||
$scope.reloadLinkTables();
|
toastr.success('Link successfully deleted.', 'Success');
|
||||||
});
|
$scope.reloadLinkTables();
|
||||||
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Disable and enable links
|
// Disable and enable links
|
||||||
|
@ -1,5 +0,0 @@
|
|||||||
$('#gpl-license').hide();
|
|
||||||
$('.license-btn').click(function () {
|
|
||||||
$('#gpl-license').slideDown();
|
|
||||||
$('.license-btn').slideUp();
|
|
||||||
});
|
|
@ -18,35 +18,13 @@
|
|||||||
<dt>Release date: {{env('POLR_RELDATE')}}</dt>
|
<dt>Release date: {{env('POLR_RELDATE')}}</dt>
|
||||||
<dt>App Install: {{env('APP_NAME')}} on {{env('APP_ADDRESS')}} on {{env('POLR_GENERATED_AT')}}<dt>
|
<dt>App Install: {{env('APP_NAME')}} on {{env('APP_ADDRESS')}} on {{env('POLR_GENERATED_AT')}}<dt>
|
||||||
</dl>
|
</dl>
|
||||||
<p>You are seeing the information above because you are logged in as an administrator.</p>
|
<p>You are seeing the information above because you are logged in as an administrator. You can edit the contents of this page by editing <code>resources/views/about.blade.php</code></p>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
<p>{{env('APP_NAME')}} is powered by Polr 2, an open source, minimalist link shortening platform.
|
<p>{{env('APP_NAME')}} is powered by Polr 2, an open source, minimalist link shortening platform. The Polr Project is in no way associated with this site.
|
||||||
Learn more at <a href='https://github.com/Cydrobolt/polr'>its Github page</a> or its <a href="//project.polr.me">project site</a>.
|
Learn more at <a href='https://github.com/Cydrobolt/polr'>its Github page</a> or its <a href="//project.polr.me">project site</a>.
|
||||||
<br />Polr is licensed under the GNU GPL License.
|
<br />Polr is licensed under the GNU GPL License.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<a href='#' class='btn btn-success license-btn'>More Information</a>
|
|
||||||
<pre class="license" id="gpl-license">
|
|
||||||
Copyright (C) 2013-2017 Chaoyi Zha
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU General Public License
|
|
||||||
as published by the Free Software Foundation; either version 2
|
|
||||||
of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
@endsection
|
@endsection
|
||||||
|
|
||||||
@section('js')
|
|
||||||
<script src='/js/about.js'></script>
|
|
||||||
@endsection
|
|
||||||
|
@ -26,6 +26,9 @@ POLR_GENERATED_AT="{{$POLR_GENERATED_AT}}"
|
|||||||
# e.g true
|
# e.g true
|
||||||
POLR_SETUP_RAN={{$POLR_SETUP_RAN}}
|
POLR_SETUP_RAN={{$POLR_SETUP_RAN}}
|
||||||
|
|
||||||
|
# Steps for obtaining a Maxmind License Key: https://docs.polrproject.org/en/latest/user-guide/maxmind-license
|
||||||
|
MAXMIND_LICENSE_KEY="{{$MAXMIND_LICENSE_KEY}}"
|
||||||
|
|
||||||
DB_CONNECTION=mysql
|
DB_CONNECTION=mysql
|
||||||
# Set to your DB host (e.g localhost)
|
# Set to your DB host (e.g localhost)
|
||||||
DB_HOST="{{{$DB_HOST}}}"
|
DB_HOST="{{{$DB_HOST}}}"
|
||||||
|
@ -65,6 +65,16 @@ Setup
|
|||||||
<option value='true'>Enable advanced analytics</option>
|
<option value='true'>Enable advanced analytics</option>
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
MaxMind GeoIP License Key (required for advanced analytics only):
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<input type='text' class='form-control' name='maxmind:license_key' value=''>
|
||||||
|
|
||||||
|
<p class='text-muted'>
|
||||||
|
To obtain a free MaxMind GeoIP license key, follow <a href="https://docs.polrproject.org/en/latest/user-guide/maxmind-license">these instructions</a> on Polr's documentation website.
|
||||||
|
</p>
|
||||||
|
|
||||||
<p>Shortening Permissions:</p>
|
<p>Shortening Permissions:</p>
|
||||||
<select name='setting:shorten_permission' class='form-control'>
|
<select name='setting:shorten_permission' class='form-control'>
|
||||||
<option value='false' selected='selected'>Anyone can shorten URLs</option>
|
<option value='false' selected='selected'>Anyone can shorten URLs</option>
|
||||||
|
Loading…
Reference in New Issue
Block a user