PHP & Redis (Predis)

If redis doesn’t have a password, don’t include password parameter in connection URL.

Connection example

private function init()
{
    $host = $this->_ci->config->item('redis_host');
    $password = $this->_ci->config->item('redis_password');
    $port = $this->_ci->config->item('redis_port');
    $db = $this->_ci->config->item('redis_db');

    $url = "tcp://{$host}:{$port}?database={$db}";
    if($password != false){
        $url .= "&password={$password}";
    }
    $this->_connection = new Client($url);
}

Content-Security-Policy Header Issue

Introduction

https://devco.re/blog/2014/04/08/security-issues-of-http-headers-2-content-security-policy/

PHP Example:

header("Content-Security-Policy: default-src *; img-src *; frame-src https:; script-src https: 'self' 'nonce-1234'; style-src https: 'self' 'nonce-1234'");

Test Results

  • ‘unsafe-inline’
    This source doesn’t work anymore. Inline scripts will still be blocked.
  • It seems ‘nonce’ is the best way to solve inline script issue
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-F1234"></script>
<script nonce="{{ $nonce }}">
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());

  gtag('config', 'G-F1234');
</script>

Reference

Webpack: jQuery is not defined issue

bootstrap.js


/*
 * dashmix.app.min.js as well.
 *
 * After that change, you won't have to include dashmix.core.min.js in your pages any more
 *

*/

// Import all vital core JS files..
import jQuery from 'jquery';
import SimpleBar from 'simplebar';
import Cookies from 'js-cookie';
import 'bootstrap';
import 'popper.js';
import 'jquery.appear';
import 'jquery-scroll-lock';

// ..and assign to window the ones that need it
window.$ = window.jQuery  = jQuery;
window.SimpleBar          = SimpleBar;
window.Cookies            = Cookies;

//Following two lines are critical
global.$ = require("jquery");
global.jQuery = global.$;

Reference:

can() not work for User Model (Laravel 5.1)

https://laravel.com/docs/5.1/authorization#via-the-user-model

Model User must have a trait:

use Illuminate\Foundation\Auth\Access\Authorizable;

Policy Example

<?php

namespace App\Policies;

use Illuminate\Auth\Access\HandlesAuthorization;

use App\User;

class UserPolicy
{
    use HandlesAuthorization;

    /**
     * Create a new policy instance.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    public function before($user, $ability){
        if ($user->isSuperAdmin()) {
            return true;
        }
    }

    public function view(User $user){
        if($user->is_admin() == true){
            return true;
        }

        return false;
    }
}

Usage in controller

$user = Auth::user();

// Need to pass $user!
logg($user->can('view', $user));

Reference:

Privacy Policy 隱私權政策範本

https://github.com/lyrasoft/chinese-privacy-policy-template

<p>非常歡迎您光臨「○○網站」(以下簡稱本網站),為了讓您能夠安心的使用本網站的各項服務與資訊,特此向您說明本網站的隱私權保護政策,以保障您的權益,請您詳閱下列內容:</p>
<h3><a id="user-content-一隱私權保護政策的適用範圍-1" class="anchor" href="#" aria-hidden="true"></a>一、隱私權保護政策的適用範圍</h3>
<p>隱私權保護政策內容,包括本網站如何處理在您使用網站服務時收集到的個人識別資料。隱私權保護政策不適用於本網站以外的相關連結網站,也不適用於非本網站所委託或參與管理的人員。</p>
<h3><a id="user-content-二個人資料的蒐集處理及利用方式-1" class="anchor" href="#" aria-hidden="true"></a>二、個人資料的蒐集、處理及利用方式</h3>
<ul>
<li>當您造訪本網站或使用本網站所提供之功能服務時,我們將視該服務功能性質,請您提供必要的個人資料,並在該特定目的範圍內處理及利用您的個人資料;非經您書面同意,本網站不會將個人資料用於其他用途。</li>
<li>本網站在您使用服務信箱、問卷調查等互動性功能時,會保留您所提供的姓名、電子郵件地址、聯絡方式及使用時間等。</li>
<li>於一般瀏覽時,伺服器會自行記錄相關行徑,包括您使用連線設備的IP位址、使用時間、使用的瀏覽器、瀏覽及點選資料記錄等,做為我們增進網站服務的參考依據,此記錄為內部應用,決不對外公佈。</li>
<li>為提供精確的服務,我們會將收集的問卷調查內容進行統計與分析,分析結果之統計數據或說明文字呈現,除供內部研究外,我們會視需要公佈統計數據及說明文字,但不涉及特定個人之資料。</li>
</ul>
<h3><a id="user-content-三資料之保護-1" class="anchor" href="#" aria-hidden="true"></a>三、資料之保護</h3>
<ul>
<li>本網站主機均設有防火牆、防毒系統等相關的各項資訊安全設備及必要的安全防護措施,加以保護網站及您的個人資料採用嚴格的保護措施,只由經過授權的人員才能接觸您的個人資料,相關處理人員皆簽有保密合約,如有違反保密義務者,將會受到相關的法律處分。</li>
<li>如因業務需要有必要委託其他單位提供服務時,本網站亦會嚴格要求其遵守保密義務,並且採取必要檢查程序以確定其將確實遵守。</li>
</ul>
<h3><a id="user-content-四網站對外的相關連結-1" class="anchor" href="#" aria-hidden="true"></a>四、網站對外的相關連結</h3>
<p>本網站的網頁提供其他網站的網路連結,您也可經由本網站所提供的連結,點選進入其他網站。但該連結網站不適用本網站的隱私權保護政策,您必須參考該連結網站中的隱私權保護政策。</p>
<h3><a id="user-content-五與第三人共用個人資料之政策-1" class="anchor" href="#" aria-hidden="true"></a>五、與第三人共用個人資料之政策</h3>
<p>本網站絕不會提供、交換、出租或出售任何您的個人資料給其他個人、團體、私人企業或公務機關,但有法律依據或合約義務者,不在此限。</p>
<p>前項但書之情形包括不限於:</p>
<ul>
<li>經由您書面同意。</li>
<li>法律明文規定。</li>
<li>為免除您生命、身體、自由或財產上之危險。</li>
<li>與公務機關或學術研究機構合作,基於公共利益為統計或學術研究而有必要,且資料經過提供者處理或蒐集者依其揭露方式無從識別特定之當事人。</li>
<li>當您在網站的行為,違反服務條款或可能損害或妨礙網站與其他使用者權益或導致任何人遭受損害時,經網站管理單位研析揭露您的個人資料是為了辨識、聯絡或採取法律行動所必要者。</li>
<li>有利於您的權益。</li>
<li>本網站委託廠商協助蒐集、處理或利用您的個人資料時,將對委外廠商或個人善盡監督管理之責。</li>
</ul>
<h3><a id="user-content-六cookie之使用-1" class="anchor" href="#" aria-hidden="true"></a>六、Cookie之使用</h3>
<p>為了提供您最佳的服務,本網站會在您的電腦中放置並取用我們的Cookie,若您不願接受Cookie的寫入,您可在您使用的瀏覽器功能項中設定隱私權等級為高,即可拒絕Cookie的寫入,但可能會導致網站某些功能無法正常執行 。</p>
<h3><a id="user-content-七隱私權保護政策之修正-1" class="anchor" href="#" aria-hidden="true"></a>七、隱私權保護政策之修正</h3>
<p>本網站隱私權保護政策將因應需求隨時進行修正,修正後的條款將刊登於網站上。</p>

tw-city-selector.js

https://dennykuo.github.io/tw-city-selector/#/advanced?id=%e6%8c%87%e5%ae%9a%e7%88%b6%e5%b1%a4-element

HTML

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/tw-city-selector.min.js"></script>

<div class="city-selector-set">
	<div>
		<!-- 縣市選單 -->
		<select class="county form-control" data-value="{{ val($model, 'city') }}"></select>
	</div>
	<div>
		<!-- 區域選單 -->
		<select class="district form-control" data-value="{{ val($model, 'district') }}"></select>
	</div>
	<div>
		<!-- 郵遞區號欄位 (建議加入 readonly 屬性,防止修改) -->
		<input class="zipcode form-control" type="text" size="3" readonly placeholder="郵遞區號" value="{{ val($model, 'zip') }}">
	</div>
</div>

Javascript

$(document).ready(function () {
    new TwCitySelector({
        el: '.city-selector-set',
        elCounty: '.county', // 在 el 裡查找 element
        elDistrict: '.district', // 在 el 裡查找 element
        elZipcode: '.zipcode', // 在 el 裡查找 element
        countyFieldName: 'city', 
        zipcodeFieldName: 'zip'
    });
});