Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade Overall Experience #11

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
9 changes: 0 additions & 9 deletions app/Helpers/LinkHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,7 @@ static public function checkIfAlreadyShortened($long_link) {
* @return boolean
*/
$shortener_domains = [
'polr.me',
'bit.ly',
'is.gd',
'tiny.cc',
'adf.ly',
'ur1.ca',
'goo.gl',
'ow.ly',
'j.mp',
't.co',
env('APP_ADDRESS')
];

Expand Down
14 changes: 14 additions & 0 deletions app/Http/Controllers/Api/ApiLinkController.php
Original file line number Diff line number Diff line change
Expand Up @@ -137,4 +137,18 @@ public function lookupLink(Request $request) {
throw new ApiException('NOT_FOUND', 'Link not found.', 404, $response_type);
}
}

public function deleteLink(Request $request) {

$response_type = $request->input('response_type');
$url_ending = $request->input('url_ending');
$link = LinkHelper::linkExists($url_ending);

if (!$link) {
throw new ApiException('DELETION ERROR','The Short Link to delete was not found', 404, $response_type);
}

$link->delete();
return "OK";
}
}
11 changes: 10 additions & 1 deletion app/Http/Controllers/LinkController.php
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,16 @@ public function performRedirect(Request $request, $short_url, $secret_key=false)
ClickHelper::recordClick($link, $request);
}
// Redirect to final destination
return redirect()->to($long_url, 301);
if (env('ENABLE_RDR_NOTICE')){
return view('redirect_notice', [
'long_url' => $long_url,
'delay_time' => env('RDR_DELAY_TIME', 10),
'rdr_message' => env('RDR_MESSAGE')
]);
}
else{
return redirect()->to($long_url, 302);
}
}

}
1 change: 1 addition & 0 deletions app/Http/Kernel.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ class Kernel extends HttpKernel

'api' => [
// \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
\App\Http\Middleware\ApiMiddleware::class,
'throttle:api',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
Expand Down
1 change: 0 additions & 1 deletion app/Providers/RouteServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ public function boot()

$this->routes(function () {
Route::middleware('api')
->prefix('api')
->group(base_path('routes/api.php'));

Route::middleware('web')
Expand Down
2 changes: 2 additions & 0 deletions bootstrap/app.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
$_ENV['APP_BASE_PATH'] ?? dirname(__DIR__)
);

require('env.php');

/*
|--------------------------------------------------------------------------
| Bind Important Interfaces
Expand Down
38 changes: 38 additions & 0 deletions bootstrap/env.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

use Dotenv\Dotenv;

if (!isset($_SERVER['HTTP_HOST'])) {
$dotenv = Dotenv::createMutable(dirname(__DIR__).'/envs/', '.env');
$dotenv->load();
}

// STARTCUSTOMLOGIC
// This logic can be used to have a different .env file for each subdomain on the main domain
$pos = mb_strpos($_SERVER['HTTP_HOST'], '.');

$prefix = '';

if ($pos) {
$prefix = mb_substr($_SERVER['HTTP_HOST'], 0, $pos);
}

$file = '.' . $prefix . '.env';
// ENDCUSTOMLOGIC

// This can be used to have a different environment file for each domain
if($_SERVER['HTTP_HOST'] == "www.example1.com" || $_SERVER['HTTP_HOST'] == "example1.com"){
$file = '.example1.env';
}

if($_SERVER['HTTP_HOST'] == "www.example2.com" || $_SERVER['HTTP_HOST'] == "example2.com"){
$file = '.example2.env';
}

// Load the custom env file if it exists, otherwise load the default .env file
if (!file_exists(dirname(__DIR__).'/envs/' . $file)) {
$file = '.env';
}

$dotenv = Dotenv::createMutable(dirname(__DIR__).'/envs/', $file);
$dotenv->load();
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public function up()
// MySQL only statement
// DB::statement("UPDATE links SET long_url_hash = crc32(long_url);");

DB::table('links')->select(['id', 'long_url_hash', 'long_url'])
DB::table('links')->select(['id', 'long_url_hash', 'long_url'])->orderBy('id')
->chunk(100, function($links) {
foreach ($links as $link) {
DB::table('links')
Expand Down
27 changes: 12 additions & 15 deletions database/migrations/2023_01_24_234401_add_secrets_key_default.php
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
Expand All @@ -13,12 +11,12 @@
*/
public function up()
{
Schema::table('links', function (Blueprint $table)
{
$table->string('secret_key')->nullable()->change();
$table->timestamp('created_at')->useCurrent()->change();
$table->timestamp('updated_at')->useCurrentOnUpdate()->change();
});
DB::statement("
ALTER TABLE links
CHANGE secret_key secret_key VARCHAR(255) CHARACTER SET utf8mb3 DEFAULT NULL COLLATE `utf8mb3_unicode_ci`,
CHANGE created_at created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
CHANGE updated_at updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP NOT NULL;
");
}

/**
Expand All @@ -28,12 +26,11 @@ public function up()
*/
public function down()
{
Schema::table('links', function (Blueprint $table)
{
$table->string('secret_key')->change();
$table->timestamp('created_at')->useCurrent()->change();
$table->timestamp('updated_at')->useCurrentOnUpdate()->change();
});

DB::statement("
ALTER TABLE links
CHANGE secret_key secret_key VARCHAR(255) DEFAULT NULL,
CHANGE created_at created_at TIMESTAMP NULL,
CHANGE updated_at updated_at TIMESTAMP NULL;
");
}
};
14 changes: 14 additions & 0 deletions docs/developer-guide/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,20 @@ Response:
}
```

### /api/v2/admin/delete_link
Arguments:

- `url_ending`: the link ending for the URL to delete. (e.g `5ga`)

An API key granted to a regular user can only be used to delete their own links.
Admins can delete any link.

Response: An OK if the link was deleted, unauthorised if not authorised to delete or 404 if the link does not exist.

Example: GET `http://example.com/api/v2/admin/delete_link?key=API_KEY_HERE&url_ending=5gk`

Response: `OK`

## HTTP Error Codes
The API will return an error code if your request was malformed or another error occured while processing your request.

Expand Down
4 changes: 2 additions & 2 deletions public/css/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
}

.site-url-field {
color: #8b1c40;
color: green;
display: inline;
}

Expand All @@ -17,7 +17,7 @@
}

.check-btn {
margin-bottom: 30px;
margin: 30px 0px;
}

#link-availability-status {
Expand Down
2 changes: 1 addition & 1 deletion public/js/constants.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
/* Polr JS Constants */

const BASE_API_PATH = '/api/v2/';
const BASE_API_PATH = '/api/v3/';
9 changes: 5 additions & 4 deletions public/js/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
$(function() {
var optionsButton = $('#show-link-options');
$('#options').hide();
var slide = 0;
var slide = 1;
$("#options").slideDown();
optionsButton.click(function() {
if (slide === 0) {
$("#options").slideDown();
Expand All @@ -14,7 +15,7 @@ $(function() {
$('#check-link-availability').click(function() {
var custom_link = $('.custom-url-field').val();
var request = $.ajax({
url: "/api/v2/link_avail_check",
url: "/api/v3/link_avail_check",
type: "POST",
data: {
link_ending: custom_link
Expand Down Expand Up @@ -54,10 +55,10 @@ $(function() {
function changeTips(tcase) {
switch (tcase) {
case 1:
setTip('Create an account to keep track of your links');
setTip('Remember to include the http:// or https:// part of your original link');
break;
case 2:
setTip('Did you know you can change the URL ending by clicking on "Link Options"?');
setTip('If you need additional help, email [email protected]');
i = 1;
break;
}
Expand Down
14 changes: 14 additions & 0 deletions resources/views/index.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,20 @@ class='form-control long-link-input' placeholder='http://' name='link-url' />
<input type="hidden" name='_token' value='{{csrf_token()}}' />
</form>

<script>
const input = document.querySelector('input[name="link-url"]');

input.addEventListener('invalid', function (event) {
if (event.target.validity.typeMismatch) {
event.target.setCustomValidity('Please enter a valid URL and ensure you have included the http:// or https:// part of the link');
}
})

input.addEventListener('input', function (event) {
event.target.setCustomValidity('');
})
</script>

<div id='tips' class='text-muted tips'>
<i class='fa fa-spinner'></i> Loading Tips...
</div>
Expand Down
5 changes: 4 additions & 1 deletion resources/views/login.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@

@section('content')
<div class="center-text">
<h1>Login</h1><br/><br/>
<h1>Login</h1><br/>
@if (env('ENABLE_LOGIN_MESSAGE') == true)
<p>{{env('LOGIN_MESSAGE')}}</p>
@endif
<div class="col-md-3"></div>
<div class="col-md-6">
<form action="login" method="POST">
Expand Down
2 changes: 2 additions & 0 deletions resources/views/snippets/navbar.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
@else
<li class="visible-xs"><a href="{{ route('admin') }}">Dashboard</a></li>
<li class="visible-xs"><a href="{{ route('admin') }}#settings">Settings</a></li>
<li class="visible-xs"><a href="{{ route('admin') }}#admin">Admin</a></li>
<li class="visible-xs"><a href="{{ route('logout') }}">Logout</a></li>
@endif
</ul>
Expand Down Expand Up @@ -58,6 +59,7 @@
<ul class="dropdown-menu pull-right" role="menu" aria-labelledby="dropdownMenu">
<li><a tabindex="-1" href="{{ route('admin') }}">Dashboard</a></li>
<li><a tabindex="-1" href="{{ route('admin') }}#settings">Settings</a></li>
<li><a tabindex="-1" href="{{ route('admin') }}#admin">Admin</a></li>
<li><a tabindex="-1" href="{{ route('logout') }}">Logout</a></li>
</ul>
</li>
Expand Down
38 changes: 18 additions & 20 deletions routes/api.php
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
<?php

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;

use App\Http\Controllers\AjaxController;
use App\Http\Controllers\AdminPaginationController;
use App\Http\Controllers\Api\ApiLinkController;
use App\Http\Controllers\Api\ApiAnalyticsController;


/*
Expand All @@ -18,22 +17,21 @@
|
*/

/*
Route::prefix('api/v2')->group(function () {
Route::post('link_avail_check', [AjaxController::class, 'checkLinkAvailability'])->name('api_link_check');
Route::post('admin/toggle_api_active', [AjaxController::class, 'toggleAPIActive'])->name('api_toggle_api_active');
Route::post('admin/generate_new_api_key', [AjaxController::class, 'generateNewAPIKey'])->name('api_generate_new_api_key');
Route::post('admin/edit_api_quota', [AjaxController::class, 'editAPIQuota'])->name('api_edit_quota');
Route::post('admin/toggle_user_active', [AjaxController::class, 'toggleUserActive'])->name('api_toggle_user_active');
Route::post('admin/change_user_role', [AjaxController::class, 'changeUserRole'])->name('api_change_user_role');
Route::post('admin/add_new_user', [AjaxController::class, 'addNewUser'])->name('api_add_new_user');
Route::post('admin/delete_user', [AjaxController::class, 'deleteUser'])->name('api_delete_user');
Route::post('admin/toggle_link', [AjaxController::class, 'toggleLink'])->name('api_toggle_link');
Route::post('admin/delete_link', [AjaxController::class, 'deleteLink'])->name('api_delete_link');
Route::post('admin/edit_link_long_url', [AjaxController::class, 'editLinkLongUrl'])->name('api_edit_link_long_url');

Route::get('admin/get_admin_users', [AdminPaginationController::class, 'paginateAdminUsers'])->name('api_get_admin_users');
Route::get('admin/get_admin_links', [AdminPaginationController::class, 'paginateAdminLinks'])->name('api_get_admin_links');
Route::get('admin/get_user_links', [AdminPaginationController::class, 'paginateUserLinks'])->name('api_get_user_links');

/* API shorten endpoints */
Route::post('action/shorten', [ApiLinkController::class, 'shortenLink'])->name('v2_api_shorten_url_post');
Route::get('action/shorten', [ApiLinkController::class, 'shortenLink'])->name('v2_api_shorten_url_get');
Route::post('action/shorten_bulk', [ApiLinkController::class, 'shortenLinksBulk'])->name('v2_api_shorten_url_bulk_post');

/* API lookup endpoints */
Route::post('action/lookup', [ApiLinkController::class, 'lookupLink'])->name('v2_api_lookup_url_post');
Route::get('action/lookup', [ApiLinkController::class, 'lookupLink'])->name('v2_api_lookup_url_get');

/* API data endpoints */
Route::get('data/link', [ApiAnalyticsController::class, 'lookupLinkStats'])->name('v2_api_link_analytics_get');
Route::post('data/link', [ApiAnalyticsController::class, 'lookupLinkStats'])->name('v2_api_link_analytics_post');

/*API delete endpoints */
Route::get('admin/delete_link', [ApiLinkController::class, 'deleteLink'])->name('v2_api_delete_link_get');
});
*/
4 changes: 2 additions & 2 deletions routes/web.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@

Route::post('/admin/action/change_password', [AdminController::class, 'changePassword'])->name('change_password');

Route::prefix('api/v2')->group(function () {
Route::prefix('api/v3')->group(function () {
Route::post('link_avail_check', [AjaxController::class, 'checkLinkAvailability'])->name('api_link_check');
Route::post('admin/toggle_api_active', [AjaxController::class, 'toggleAPIActive'])->name('api_toggle_api_active');
Route::post('admin/generate_new_api_key', [AjaxController::class, 'generateNewAPIKey'])->name('api_generate_new_api_key');
Expand All @@ -87,4 +87,4 @@
Route::get('admin/get_admin_users', [AdminPaginationController::class, 'paginateAdminUsers'])->name('api_get_admin_users');
Route::get('admin/get_admin_links', [AdminPaginationController::class, 'paginateAdminLinks'])->name('api_get_admin_links');
Route::get('admin/get_user_links', [AdminPaginationController::class, 'paginateUserLinks'])->name('api_get_user_links');
});
});