Merge pull request 'various-fixes' (#55) from various-fixes into master
All checks were successful
🚀 Deploy website on push / 🎉 Deploy (push) Successful in 20s

Reviewed-on: #55
This commit is contained in:
Rohit Pai 2024-06-22 19:02:57 +01:00
commit 7d6eeb2310
29 changed files with 139 additions and 511 deletions

View File

@ -18,7 +18,8 @@
"ext-libxml": "*",
"donatello-za/rake-php-plus": "^1.0",
"phpmailer/phpmailer": "^6.9",
"onelogin/php-saml": "^4.1"
"onelogin/php-saml": "^4.1",
"ext-mbstring": "*"
},
"repositories": [
{

View File

@ -674,6 +674,7 @@ EOD;
public function changeHTMLSrc(string $body, string $to, string $from): string
{
$htmlDoc = new DOMDocument();
$body = mb_convert_encoding($body, "HTML-ENTITIES", "UTF-8");
$htmlDoc->loadHTML($body, LIBXML_NOERROR);
$doc = $htmlDoc->getElementsByTagName('body')->item(0);
$imgs = $doc->getElementsByTagName('img');
@ -708,7 +709,8 @@ EOD;
$newBody = '';
foreach ($doc->childNodes as $node)
{
$newBody .= $htmlDoc->saveHTML($node);
$newHTML = $htmlDoc->saveHTML($node);
$newBody .= mb_convert_encoding($newHTML, "UTF-8", mb_detect_encoding($newHTML));
}
return $newBody;
}

138
dist/api/user/user.php vendored
View File

@ -1,138 +0,0 @@
<?php
namespace api\user;
use Firebase\JWT\JWT;
use PDO;
require_once __DIR__ . "/../utils/config.php";
/**
* User Class
* Define all functions which either check, update or delete user data
*/
class user
{
/**
* Check if user exists and can be logged in
* @param $username string - Username
* @param $password string - Password
* @return bool - True if logged in, false if not
*/
function checkUser(string $username, string $password): bool
{
$conn = dbConn();
$stmt = $conn->prepare("SELECT * FROM users WHERE username = :username");
$stmt->bindParam(":username", $username);
$stmt->execute();
// set the resulting array to associative
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
if ($result)
{
if (password_verify($password, $result[0]["password"]))
{
return true;
}
return false;
}
return false;
}
/**
* Create a JWT token
* @param $username string - Username
* @return string - JWT token
*/
function createToken(string $username): string
{
$now = time();
$future = strtotime('+6 hour',$now);
$secretKey = getSecretKey();
$payload = [
"jti"=>$username,
"iat"=>$now,
"exp"=>$future
];
return JWT::encode($payload,$secretKey,"HS256");
}
/**
* Check if email is already in use
* @param string $email - Email to check
* @return bool - True if email exists, false if not
*/
function checkEmail(string $email): bool
{
$conn = dbConn();
$stmt = $conn->prepare("SELECT * FROM users WHERE email = :email");
$stmt->bindParam(":email", $email);
$stmt->execute();
// set the resulting array to associative
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
if ($result)
{
return true;
}
return false;
}
/**
* Send a verification email to the user
* @param $email - email address of the user
* @return string - verification code
*/
function sendResetEmail($email): string
{
//generate a random token and email the address
$token = uniqid("rpe-");
$headers1 = "From: noreply@rohitpai.co.uk\r\n";
$headers1 .= "MIME-Version: 1.0\r\n";
$headers1 .= "Content-Type: text/html; charset=UTF-8\r\n";
$message = "
<!doctype html>
<html lang='en'>
<head>
<meta charset='UTF-8'>
<meta name='viewport' content='width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0'>
<meta http-equiv='X-UA-Compatible' content='ie=edge'>
<title>Document</title>
</head>
<body>
<h1>Reset Password Verification Code</h1>
<br>
<p>Please enter the following code to reset your password: $token</p>
</body>
</html>
";
mail($email, "Reset Password Verification Code", $message, $headers1);
return $token;
}
/**
* Change password for an email with new password
* @param $email string Email
* @param $password string Password
* @return bool - true if the password was changed, false if not
*/
function changePassword(string $email, string $password): bool
{
$conn = dbConn();
$stmt = $conn->prepare("UPDATE users SET password = :password WHERE email = :email");
$newPwd = password_hash($password, PASSWORD_BCRYPT);
$stmt->bindParam(":password", $newPwd);
$stmt->bindParam(":email", $email);
if ($stmt->execute())
{
return true;
}
return false;
}
}

View File

@ -17,7 +17,7 @@ class userRoutes implements routesInterface
private Auth $samlAuth;
/**
* constructor used to instantiate a base user routes, to be used in the index.php file.
* constructor used to instantiate base user routes, to be used in the index.php file.
* @param App $app - the slim app used to create the routes
* @throws Error
*/
@ -181,7 +181,7 @@ class userRoutes implements routesInterface
$inactive = 60 * 60 * 48; // 2 days
$_SESSION["timeout"] = time() + $inactive;
return $response->withHeader("Location", "https://rohitpai.co.uk/editor/editor.html")->withStatus(302);
return $response->withHeader("Location", "https://rohitpai.co.uk/editor/")->withStatus(302);
}
$response->getBody()->write(json_encode(array("error" => "Unauthorised")));
@ -214,4 +214,4 @@ class userRoutes implements routesInterface
return $response->withStatus(500);
});
}
}
}

View File

@ -1,142 +0,0 @@
<?php
namespace api\user;
use Firebase\JWT\JWT;
use PDO;
use function api\utils\dbConn;
use function api\utils\getSecretKey;
require_once __DIR__ . "/../utils/config.php";
/**
* User Class
* Define all functions which either check, update or delete userData data
*/
class userData
{
/**
* Check if userData exists and can be logged in
* @param $username string - Username
* @param $password string - Password
* @return bool - True if logged in, false if not
*/
public function checkUser(string $username, string $password): bool
{
$conn = dbConn();
$stmt = $conn->prepare("SELECT * FROM users WHERE username = :username");
$stmt->bindParam(":username", $username);
$stmt->execute();
// set the resulting array to associative
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
if ($result)
{
if (password_verify($password, $result[0]["password"]))
{
return true;
}
return false;
}
return false;
}
/**
* Create a JWT token
* @param $username string - Username
* @return string - JWT token
*/
public function createToken(string $username): string
{
$now = time();
$future = strtotime('+2 day', $now);
$secretKey = getSecretKey();
$payload = [
"jti" => $username,
"iat" => $now,
"exp" => $future
];
return JWT::encode($payload, $secretKey, "HS256");
}
/**
* Check if email is already in use
* @param string $email - Email to check
* @return bool - True if email exists, false if not
*/
public function checkEmail(string $email): bool
{
$conn = dbConn();
$stmt = $conn->prepare("SELECT * FROM users WHERE email = :email");
$stmt->bindParam(":email", $email);
$stmt->execute();
// set the resulting array to associative
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
if ($result)
{
return true;
}
return false;
}
/**
* Send a verification email to the userData
* @param $email - email address of the userData
* @return string - verification code
*/
public function sendResetEmail($email): string
{
//generate a random token and email the address
$token = uniqid("rpe-");
$headers1 = "From: noreply@rohitpai.co.uk\r\n";
$headers1 .= "MIME-Version: 1.0\r\n";
$headers1 .= "Content-Type: text/html; charset=UTF-8\r\n";
$message = "
<!doctype html>
<html lang='en'>
<head>
<meta charset='UTF-8'>
<meta name='viewport' content='width=device-width, userData-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0'>
<meta http-equiv='X-UA-Compatible' content='ie=edge'>
<title>Document</title>
</head>
<body>
<h1>Reset Password Verification Code</h1>
<br>
<p>Please enter the following code to reset your password: $token</p>
</body>
</html>
";
mail($email, "Reset Password Verification Code", $message, $headers1);
return $token;
}
/**
* Change password for an email with new password
* @param $email string Email
* @param $password string Password
* @return bool - true if the password was changed, false if not
*/
public function changePassword(string $email, string $password): bool
{
$conn = dbConn();
$stmt = $conn->prepare("UPDATE users SET password = :password WHERE email = :email");
$newPwd = password_hash($password, PASSWORD_BCRYPT);
$stmt->bindParam(":password", $newPwd);
$stmt->bindParam(":email", $email);
if ($stmt->execute())
{
return true;
}
return false;
}
}

View File

@ -1,168 +0,0 @@
<?php
namespace api\user;
require_once __DIR__ . "/../utils/routesInterface.php";
require_once "userData.php";
use api\utils\routesInterface;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Slim\App;
class userRoutes implements routesInterface
{
private userData $user;
/**
* constructor used to instantiate a base user routes, to be used in the index.php file.
* @param App $app - the slim app used to create the routes
*/
public function __construct(App $app)
{
$this->user = new userData();
$this->createRoutes($app);
}
/**
* creates the routes for the user
* @param App $app - the slim app used to create the routes
* @return void - returns nothing
*/
public function createRoutes(App $app): void
{
$app->post("/user/login", function (Request $request, Response $response)
{
// get request data
$data = $request->getParsedBody();
if (empty($data["username"]) || empty($data["password"]))
{
// uh oh user sent empty data
return $response->withStatus(400);
}
if ($this->user->checkUser($data["username"], $data["password"]))
{
// yay, user is logged in
$_SESSION["token"] = $this->user->createToken($data["username"]);
$_SESSION["username"] = $data["username"];
$inactive = 60 * 60 * 48; // 2 days
$_SESSION["timeout"] = time() + $inactive;
$response->getBody()->write(json_encode(array("token" => $_SESSION["token"])));
return $response;
}
$response->getBody()->write(json_encode(array("error" => "Unauthorised")));
return $response->withStatus(401);
});
$app->get("/user/logout", function (Request $request, Response $response)
{
session_unset();
return $response;
});
$app->get("/user/isLoggedIn", function (Request $request, Response $response)
{
if (empty($_SESSION["token"]) && empty($_SESSION["username"]))
{
// uh oh user not logged in
return $response->withStatus(401);
}
$inactive = 60 * 60 * 48; // 2 days
$sessionLife = time() - $_SESSION["timeout"];
if ($sessionLife > $inactive)
{
// uh oh user session expired
session_destroy();
return $response->withStatus(401);
}
if (empty($_SESSION["token"]))
{
// user is logged in but no token was created
$_SESSION["token"] = $this->user->createToken($_SESSION["username"]);
return $response->withStatus(201);
}
$response->getBody()->write(json_encode(array("token" => $_SESSION["token"])));
return $response;
});
$app->get("/user/checkResetEmail/{email}", function (Request $request, Response $response, array $args)
{
if (empty($args["email"]))
{
// uh oh sent empty data
return $response->withStatus(400);
}
if ($this->user->checkEmail($args["email"]))
{
// yay email does exist
$_SESSION["resetToken"] = $this->user->sendResetEmail($args["email"]);
$_SESSION["resetEmail"] = $args["email"];
return $response;
}
return $response->withStatus(404);
});
$app->get("/user/resendEmail", function (Request $request, Response $response)
{
if (empty($_SESSION["resetToken"]))
{
// uh oh not authorized to resend email
return $response->withStatus(401);
}
$_SESSION["resetToken"] = $this->user->sendResetEmail($_SESSION["resetEmail"]);
return $response;
});
$app->get("/user/checkResetCode/{code}", function (Request $request, Response $response, array $args)
{
if (empty($args["code"]))
{
// uh oh sent empty data
return $response->withStatus(400);
}
if ($_SESSION["resetToken"] === $args["code"])
{
// yay, code code matches
return $response;
}
return $response->withStatus(401);
});
$app->post("/user/changePassword", function (Request $request, Response $response)
{
if (empty($_SESSION["resetToken"]) && empty($_SESSION["resetEmail"]))
{
// uh oh not authorized to change password
return $response->withStatus(401);
}
$data = $request->getParsedBody();
if (empty($data["password"]))
{
// uh oh sent empty data
return $response->withStatus(400);
}
if ($this->user->changePassword($_SESSION["resetEmail"], $data["password"]))
{
// yay, password changed
unset($_SESSION["resetToken"]);
unset($_SESSION["resetEmail"]);
return $response->withStatus(201);
}
return $response->withStatus(500);
});
}
}

File diff suppressed because one or more lines are too long

12
dist/blog/css/prism.css vendored Normal file
View File

@ -0,0 +1,12 @@
/* PrismJS 1.29.0
https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript+abap+abnf+actionscript+ada+agda+al+antlr4+apacheconf+apex+apl+applescript+aql+arduino+arff+armasm+arturo+asciidoc+aspnet+asm6502+asmatmel+autohotkey+autoit+avisynth+avro-idl+awk+bash+basic+batch+bbcode+bbj+bicep+birb+bison+bnf+bqn+brainfuck+brightscript+bro+bsl+c+csharp+cpp+cfscript+chaiscript+cil+cilkc+cilkcpp+clojure+cmake+cobol+coffeescript+concurnas+csp+cooklang+coq+crystal+css-extras+csv+cue+cypher+d+dart+dataweave+dax+dhall+diff+django+dns-zone-file+docker+dot+ebnf+editorconfig+eiffel+ejs+elixir+elm+etlua+erb+erlang+excel-formula+fsharp+factor+false+firestore-security-rules+flow+fortran+ftl+gml+gap+gcode+gdscript+gedcom+gettext+gherkin+git+glsl+gn+linker-script+go+go-module+gradle+graphql+groovy+haml+handlebars+haskell+haxe+hcl+hlsl+hoon+http+hpkp+hsts+ichigojam+icon+icu-message-format+idris+ignore+inform7+ini+io+j+java+javadoc+javadoclike+javastacktrace+jexl+jolie+jq+jsdoc+js-extras+json+json5+jsonp+jsstacktrace+js-templates+julia+keepalived+keyman+kotlin+kumir+kusto+latex+latte+less+lilypond+liquid+lisp+livescript+llvm+log+lolcode+lua+magma+makefile+markdown+markup-templating+mata+matlab+maxscript+mel+mermaid+metafont+mizar+mongodb+monkey+moonscript+n1ql+n4js+nand2tetris-hdl+naniscript+nasm+neon+nevod+nginx+nim+nix+nsis+objectivec+ocaml+odin+opencl+openqasm+oz+parigp+parser+pascal+pascaligo+psl+pcaxis+peoplecode+perl+php+phpdoc+php-extras+plant-uml+plsql+powerquery+powershell+processing+prolog+promql+properties+protobuf+pug+puppet+pure+purebasic+purescript+python+qsharp+q+qml+qore+r+racket+cshtml+jsx+tsx+reason+regex+rego+renpy+rescript+rest+rip+roboconf+robotframework+ruby+rust+sas+sass+scss+scala+scheme+shell-session+smali+smalltalk+smarty+sml+solidity+solution-file+soy+sparql+splunk-spl+sqf+sql+squirrel+stan+stata+iecst+stylus+supercollider+swift+systemd+t4-templating+t4-cs+t4-vb+tap+tcl+tt2+textile+toml+tremor+turtle+twig+typescript+typoscript+unrealscript+uorazor+uri+v+vala+vbnet+velocity+verilog+vhdl+vim+visual-basic+warpscript+wasm+web-idl+wgsl+wiki+wolfram+wren+xeora+xml-doc+xojo+xquery+yaml+yang+zig&plugins=line-numbers+show-language+inline-color+previewers+unescaped-markup+toolbar+copy-to-clipboard+download-button+match-braces */
code[class*=language-],pre[class*=language-]{color:#000;background:0 0;text-shadow:0 1px #fff;font-family:Consolas,Monaco,'Andale Mono','Ubuntu Mono',monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}code[class*=language-] ::-moz-selection,code[class*=language-]::-moz-selection,pre[class*=language-] ::-moz-selection,pre[class*=language-]::-moz-selection{text-shadow:none;background:#b3d4fc}code[class*=language-] ::selection,code[class*=language-]::selection,pre[class*=language-] ::selection,pre[class*=language-]::selection{text-shadow:none;background:#b3d4fc}@media print{code[class*=language-],pre[class*=language-]{text-shadow:none}}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto}:not(pre)>code[class*=language-],pre[class*=language-]{background:#f5f2f0}:not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em;white-space:normal}.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#708090}.token.punctuation{color:#999}.token.namespace{opacity:.7}.token.boolean,.token.constant,.token.deleted,.token.number,.token.property,.token.symbol,.token.tag{color:#905}.token.attr-name,.token.builtin,.token.char,.token.inserted,.token.selector,.token.string{color:#690}.language-css .token.string,.style .token.string,.token.entity,.token.operator,.token.url{color:#9a6e3a;background:hsla(0,0%,100%,.5)}.token.atrule,.token.attr-value,.token.keyword{color:#07a}.token.class-name,.token.function{color:#dd4a68}.token.important,.token.regex,.token.variable{color:#e90}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}
pre[class*=language-].line-numbers{position:relative;padding-left:3.8em;counter-reset:linenumber}pre[class*=language-].line-numbers>code{position:relative;white-space:inherit}.line-numbers .line-numbers-rows{position:absolute;pointer-events:none;top:0;font-size:100%;left:-3.8em;width:3em;letter-spacing:-1px;border-right:1px solid #999;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.line-numbers-rows>span{display:block;counter-increment:linenumber}.line-numbers-rows>span:before{content:counter(linenumber);color:#999;display:block;padding-right:.8em;text-align:right}
div.code-toolbar{position:relative}div.code-toolbar>.toolbar{position:absolute;z-index:10;top:.3em;right:.2em;transition:opacity .3s ease-in-out;opacity:0}div.code-toolbar:hover>.toolbar{opacity:1}div.code-toolbar:focus-within>.toolbar{opacity:1}div.code-toolbar>.toolbar>.toolbar-item{display:inline-block}div.code-toolbar>.toolbar>.toolbar-item>a{cursor:pointer}div.code-toolbar>.toolbar>.toolbar-item>button{background:0 0;border:0;color:inherit;font:inherit;line-height:normal;overflow:visible;padding:0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}div.code-toolbar>.toolbar>.toolbar-item>a,div.code-toolbar>.toolbar>.toolbar-item>button,div.code-toolbar>.toolbar>.toolbar-item>span{color:#bbb;font-size:.8em;padding:0 .5em;background:#f5f2f0;background:rgba(224,224,224,.2);box-shadow:0 2px 0 0 rgba(0,0,0,.2);border-radius:.5em}div.code-toolbar>.toolbar>.toolbar-item>a:focus,div.code-toolbar>.toolbar>.toolbar-item>a:hover,div.code-toolbar>.toolbar>.toolbar-item>button:focus,div.code-toolbar>.toolbar>.toolbar-item>button:hover,div.code-toolbar>.toolbar>.toolbar-item>span:focus,div.code-toolbar>.toolbar>.toolbar-item>span:hover{color:inherit;text-decoration:none}
span.inline-color-wrapper{background:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyIDIiPjxwYXRoIGZpbGw9ImdyYXkiIGQ9Ik0wIDBoMnYySDB6Ii8+PHBhdGggZmlsbD0id2hpdGUiIGQ9Ik0wIDBoMXYxSDB6TTEgMWgxdjFIMXoiLz48L3N2Zz4=);background-position:center;background-size:110%;display:inline-block;height:1.333ch;width:1.333ch;margin:0 .333ch;box-sizing:border-box;border:1px solid #fff;outline:1px solid rgba(0,0,0,.5);overflow:hidden}span.inline-color{display:block;height:120%;width:120%}
.prism-previewer,.prism-previewer:after,.prism-previewer:before{position:absolute;pointer-events:none}.prism-previewer,.prism-previewer:after{left:50%}.prism-previewer{margin-top:-48px;width:32px;height:32px;margin-left:-16px;z-index:10;opacity:0;-webkit-transition:opacity .25s;-o-transition:opacity .25s;transition:opacity .25s}.prism-previewer.flipped{margin-top:0;margin-bottom:-48px}.prism-previewer:after,.prism-previewer:before{content:'';position:absolute;pointer-events:none}.prism-previewer:before{top:-5px;right:-5px;left:-5px;bottom:-5px;border-radius:10px;border:5px solid #fff;box-shadow:0 0 3px rgba(0,0,0,.5) inset,0 0 10px rgba(0,0,0,.75)}.prism-previewer:after{top:100%;width:0;height:0;margin:5px 0 0 -7px;border:7px solid transparent;border-color:rgba(255,0,0,0);border-top-color:#fff}.prism-previewer.flipped:after{top:auto;bottom:100%;margin-top:0;margin-bottom:5px;border-top-color:rgba(255,0,0,0);border-bottom-color:#fff}.prism-previewer.active{opacity:1}.prism-previewer-angle:before{border-radius:50%;background:#fff}.prism-previewer-angle:after{margin-top:4px}.prism-previewer-angle svg{width:32px;height:32px;-webkit-transform:rotate(-90deg);-moz-transform:rotate(-90deg);-ms-transform:rotate(-90deg);-o-transform:rotate(-90deg);transform:rotate(-90deg)}.prism-previewer-angle[data-negative] svg{-webkit-transform:scaleX(-1) rotate(-90deg);-moz-transform:scaleX(-1) rotate(-90deg);-ms-transform:scaleX(-1) rotate(-90deg);-o-transform:scaleX(-1) rotate(-90deg);transform:scaleX(-1) rotate(-90deg)}.prism-previewer-angle circle{fill:transparent;stroke:#2d3438;stroke-opacity:.9;stroke-width:32;stroke-dasharray:0,500}.prism-previewer-gradient{background-image:linear-gradient(45deg,#bbb 25%,transparent 25%,transparent 75%,#bbb 75%,#bbb),linear-gradient(45deg,#bbb 25%,#eee 25%,#eee 75%,#bbb 75%,#bbb);background-size:10px 10px;background-position:0 0,5px 5px;width:64px;margin-left:-32px}.prism-previewer-gradient:before{content:none}.prism-previewer-gradient div{position:absolute;top:-5px;left:-5px;right:-5px;bottom:-5px;border-radius:10px;border:5px solid #fff;box-shadow:0 0 3px rgba(0,0,0,.5) inset,0 0 10px rgba(0,0,0,.75)}.prism-previewer-color{background-image:linear-gradient(45deg,#bbb 25%,transparent 25%,transparent 75%,#bbb 75%,#bbb),linear-gradient(45deg,#bbb 25%,#eee 25%,#eee 75%,#bbb 75%,#bbb);background-size:10px 10px;background-position:0 0,5px 5px}.prism-previewer-color:before{background-color:inherit;background-clip:padding-box}.prism-previewer-easing{margin-top:-76px;margin-left:-30px;width:60px;height:60px;background:#333}.prism-previewer-easing.flipped{margin-bottom:-116px}.prism-previewer-easing svg{width:60px;height:60px}.prism-previewer-easing circle{fill:#2d3438;stroke:#fff}.prism-previewer-easing path{fill:none;stroke:#fff;stroke-linecap:round;stroke-width:4}.prism-previewer-easing line{stroke:#fff;stroke-opacity:.5;stroke-width:2}@-webkit-keyframes prism-previewer-time{0%{stroke-dasharray:0,500;stroke-dashoffset:0}50%{stroke-dasharray:100,500;stroke-dashoffset:0}100%{stroke-dasharray:0,500;stroke-dashoffset:-100}}@-o-keyframes prism-previewer-time{0%{stroke-dasharray:0,500;stroke-dashoffset:0}50%{stroke-dasharray:100,500;stroke-dashoffset:0}100%{stroke-dasharray:0,500;stroke-dashoffset:-100}}@-moz-keyframes prism-previewer-time{0%{stroke-dasharray:0,500;stroke-dashoffset:0}50%{stroke-dasharray:100,500;stroke-dashoffset:0}100%{stroke-dasharray:0,500;stroke-dashoffset:-100}}@keyframes prism-previewer-time{0%{stroke-dasharray:0,500;stroke-dashoffset:0}50%{stroke-dasharray:100,500;stroke-dashoffset:0}100%{stroke-dasharray:0,500;stroke-dashoffset:-100}}.prism-previewer-time:before{border-radius:50%;background:#fff}.prism-previewer-time:after{margin-top:4px}.prism-previewer-time svg{width:32px;height:32px;-webkit-transform:rotate(-90deg);-moz-transform:rotate(-90deg);-ms-transform:rotate(-90deg);-o-transform:rotate(-90deg);transform:rotate(-90deg)}.prism-previewer-time circle{fill:transparent;stroke:#2d3438;stroke-opacity:.9;stroke-width:32;stroke-dasharray:0,500;stroke-dashoffset:0;-webkit-animation:prism-previewer-time linear infinite 3s;-moz-animation:prism-previewer-time linear infinite 3s;-o-animation:prism-previewer-time linear infinite 3s;animation:prism-previewer-time linear infinite 3s}
[class*=lang-] script[type='text/plain'],[class*=language-] script[type='text/plain'],script[type='text/plain'][class*=lang-],script[type='text/plain'][class*=language-]{display:block;font:100% Consolas,Monaco,monospace;white-space:pre;overflow:auto}
.token.punctuation.brace-hover,.token.punctuation.brace-selected{outline:solid 1px}.rainbow-braces .token.punctuation.brace-level-1,.rainbow-braces .token.punctuation.brace-level-5,.rainbow-braces .token.punctuation.brace-level-9{color:#e50;opacity:1}.rainbow-braces .token.punctuation.brace-level-10,.rainbow-braces .token.punctuation.brace-level-2,.rainbow-braces .token.punctuation.brace-level-6{color:#0b3;opacity:1}.rainbow-braces .token.punctuation.brace-level-11,.rainbow-braces .token.punctuation.brace-level-3,.rainbow-braces .token.punctuation.brace-level-7{color:#26f;opacity:1}.rainbow-braces .token.punctuation.brace-level-12,.rainbow-braces .token.punctuation.brace-level-4,.rainbow-braces .token.punctuation.brace-level-8{color:#e0e;opacity:1}
/*gruvbox light*/
code[class*=language-],pre[class*=language-]{color:#3c3836;font-family:Consolas,Monaco,"Andale Mono",monospace;direction:ltr;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}code[class*=language-] ::-moz-selection,code[class*=language-]::-moz-selection,pre[class*=language-] ::-moz-selection,pre[class*=language-]::-moz-selection{color:#282828;background:#a89984}code[class*=language-] ::selection,code[class*=language-]::selection,pre[class*=language-] ::selection,pre[class*=language-]::selection{color:#282828;background:#a89984}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto}:not(pre)>code[class*=language-],pre[class*=language-]{background:#f9f5d7}:not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em}.token.attr-name,.token.attr-value,.token.attr-value .punctuation,.token.cdata,.token.comment,.token.operator,.token.prolog,.token.punctuation{color:#7c6f64}.token.atrule,.token.boolean,.token.constant,.token.delimiter,.token.important,.token.keyword,.token.property,.token.selector,.token.variable{color:#9d0006}.token.builtin,.token.doctype,.token.function,.token.tag,.token.tag .punctuation{color:#b57614}.token.entity,.token.number,.token.symbol{color:#8f3f71}.token.char,.token.string,.token.url{color:#797403}.token.url{text-decoration:underline}.token.regex{background:#797403}.token.bold{font-weight:700}.token.italic{font-style:italic}.token.inserted{background:#7c6f64}.token.deleted{background:#9d0006}

View File

@ -1 +1 @@
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,user-scalable=no,initial-scale=1,maximum-scale=1,minimum-scale=1"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Rohit Pai - Blog</title><meta name="title" content="Rohit Pai - Blog"><meta name="description" content="This is all the blog posts that Rohit Pai has posted. You'll find posts on various topics, mostly on tech but some on various other random topics."><meta name="keywords" content="Blog, all posts, rohit, pai, rohit pai, tech, web development, self-hosting, hosting"><meta name="robots" content="index, follow"><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><meta name="language" content="English"><meta name="author" content="Rohit Pai"><link rel="stylesheet" href="/blog/css/main.css"><script src="https://kit.fontawesome.com/ed3c25598e.js" crossorigin="anonymous"></script><script type="text/javascript" src="https://platform-api.sharethis.com/js/sharethis.js#property=6550cdc47a115e0012964576&product=sop" async="async"></script></head><body><nav><input type="checkbox" id="nav-check"><h1><a href="/" class="link">rohit pai</a></h1><div class="nav-btn"><label for="nav-check"><span></span> <span></span> <span></span></label></div><ul><li><a href="/#about" class="textShadow link">about</a></li><li><a href="/#curriculumVitae" class="textShadow link">cv</a></li><li><a href="/#projects" class="textShadow link">projects</a></li><li><a href="/#contact" class="textShadow link">contact</a></li><li><a href="/blog" class="textShadow link active">blog</a></li></ul></nav><header><div><h1>full stack developer</h1><a href="/#sayHello" class="btn btnPrimary boxShadowIn boxShadowOut">Contact Me</a> <a href="" id="arrow"><i class="fa-solid fa-chevron-down"></i></a></div></header><div class="menuBar"><div class="menu"><ul><li><a href="/blog" class="link active">All posts</a></li><li><a href="/blog/category" class="link">categories</a></li><li><label for="searchField" aria-hidden="true" hidden>search</label> <input type="search" name="search" id="searchField" placeholder="Search..."> <button type="submit" id="searchBtn" class="btn btnPrimary"><i class="fa fa-search"></i></button></li></ul></div></div><main id="main"></main><div class="modal-container" id="cookiePopup"><div class="modal"><div class="modal-content"><h2><i class="fas fa-cookie-bite"></i> Hey I use cookies btw</h2><p>Just to let you know, I use cookies to give you the best experience on my blog. By clicking agree I'll assume that you are happy with it. <a href="/blog/policy/cookie" class="link">Read more</a></p><div class="flexRow"><button class="btn btnPrimary" id="cookieAccept">agree</button></div></div></div></div><footer class="flexRow"><div class="nav"><ul><li><a href="/blog/policy/privacy" class="link">privacy policy</a></li><li><a href="/blog/policy/cookie" class="link">cookie policy</a></li></ul></div><p>&copy; <span id="year"></span> Rohit Pai all rights reserved</p><div class="button"><button id="goBackToTop"><i class="fa-solid fa-chevron-up"></i></button></div></footer><script src="/js/typewriter.js"></script><script src="/blog/js/index.js"></script><script id="dsq-count-scr" src="https://rohitpaiportfolio.disqus.com/count.js" async></script></body></html>
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,user-scalable=no,initial-scale=1,maximum-scale=1,minimum-scale=1"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Rohit Pai - Blog</title><meta name="title" content="Rohit Pai - Blog"><meta name="description" content="This is all the blog posts that Rohit Pai has posted. You'll find posts on various topics, mostly on tech but some on various other random topics."><meta name="keywords" content="Blog, all posts, rohit, pai, rohit pai, tech, web development, self-hosting, hosting"><meta name="robots" content="index, follow"><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><meta name="language" content="English"><meta name="author" content="Rohit Pai"><link rel="stylesheet" href="/blog/css/prism.css"><link rel="stylesheet" href="/blog/css/main.css"><script src="https://kit.fontawesome.com/ed3c25598e.js" crossorigin="anonymous"></script><script type="text/javascript" src="https://platform-api.sharethis.com/js/sharethis.js#property=6550cdc47a115e0012964576&product=sop" async="async"></script></head><body><nav><input type="checkbox" id="nav-check"><h1><a href="/" class="link">rohit pai</a></h1><div class="nav-btn"><label for="nav-check"><span></span> <span></span> <span></span></label></div><ul><li><a href="/#about" class="textShadow link">about</a></li><li><a href="/#curriculumVitae" class="textShadow link">cv</a></li><li><a href="/#projects" class="textShadow link">projects</a></li><li><a href="/#contact" class="textShadow link">contact</a></li><li><a href="/blog" class="textShadow link active">blog</a></li></ul></nav><header><div><h1>full stack developer</h1><a href="/#sayHello" class="btn btnPrimary boxShadowIn boxShadowOut">Contact Me</a> <a href="" id="arrow"><i class="fa-solid fa-chevron-down"></i></a></div></header><div class="menuBar"><div class="menu"><ul><li><a href="/blog" class="link active">All posts</a></li><li><a href="/blog/category" class="link">categories</a></li><li><label for="searchField" aria-hidden="true" hidden>search</label> <input type="search" name="search" id="searchField" placeholder="Search..."> <button type="submit" id="searchBtn" class="btn btnPrimary"><i class="fa fa-search"></i></button></li></ul></div></div><main id="main"></main><div class="modal-container" id="cookiePopup"><div class="modal"><div class="modal-content"><h2><i class="fas fa-cookie-bite"></i> Hey I use cookies btw</h2><p>Just to let you know, I use cookies to give you the best experience on my blog. By clicking agree I'll assume that you are happy with it. <a href="/blog/policy/cookie" class="link">Read more</a></p><div class="flexRow"><button class="btn btnPrimary" id="cookieAccept">agree</button></div></div></div></div><footer class="flexRow"><div class="nav"><ul><li><a href="/blog/policy/privacy" class="link">privacy policy</a></li><li><a href="/blog/policy/cookie" class="link">cookie policy</a></li></ul></div><p>&copy; <span id="year"></span> Rohit Pai all rights reserved</p><div class="button"><button id="goBackToTop"><i class="fa-solid fa-chevron-up"></i></button></div></footer><script src="/js/typewriter.js"></script><script src="/blog/js/prism.js"></script><script src="/blog/js/index.js"></script><script id="dsq-count-scr" src="https://rohitpaiportfolio.disqus.com/count.js" async></script></body></html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

4
dist/index.html vendored

File diff suppressed because one or more lines are too long

2
run.sh Normal file
View File

@ -0,0 +1,2 @@
#!/bin/bash
npm start

View File

@ -674,6 +674,7 @@ EOD;
public function changeHTMLSrc(string $body, string $to, string $from): string
{
$htmlDoc = new DOMDocument();
$body = mb_convert_encoding($body, "HTML-ENTITIES", "UTF-8");
$htmlDoc->loadHTML($body, LIBXML_NOERROR);
$doc = $htmlDoc->getElementsByTagName('body')->item(0);
$imgs = $doc->getElementsByTagName('img');
@ -708,7 +709,8 @@ EOD;
$newBody = '';
foreach ($doc->childNodes as $node)
{
$newBody .= $htmlDoc->saveHTML($node);
$newHTML = $htmlDoc->saveHTML($node);
$newBody .= mb_convert_encoding($newHTML, "UTF-8", mb_detect_encoding($newHTML));
}
return $newBody;
}

View File

@ -17,7 +17,7 @@ class userRoutes implements routesInterface
private Auth $samlAuth;
/**
* constructor used to instantiate a base user routes, to be used in the index.php file.
* constructor used to instantiate base user routes, to be used in the index.php file.
* @param App $app - the slim app used to create the routes
* @throws Error
*/
@ -168,27 +168,24 @@ class userRoutes implements routesInterface
$this->samlAuth->processResponse();
$attributes = $this->samlAuth->getAttributes();
// $username = $attributes["username"][0];
// $email = $attributes["email"][0];
$username = $attributes["username"][0];
$email = $attributes["email"][0];
$response->getBody()->write(json_encode($attributes));
return $response;
if ($this->user->checkSAMLUser($username, $email))
{
// yay, user is logged in
$_SESSION["token"] = $this->user->createToken($username);
$_SESSION["username"] = $username;
$_SESSION["email"] = $email;
// if ($this->user->checkSAMLUser($username, $email))
// {
// // yay, user is logged in
// $_SESSION["token"] = $this->user->createToken($username);
// $_SESSION["username"] = $username;
// $_SESSION["email"] = $email;
//
// $inactive = 60 * 60 * 48; // 2 days
// $_SESSION["timeout"] = time() + $inactive;
//
// return $response->withHeader("Location", "https://rohitpai.co.uk/editor/editor.html")->withStatus(302);
// }
//
// $response->getBody()->write(json_encode(array("error" => "Unauthorised")));
// return $response->withStatus(401);
$inactive = 60 * 60 * 48; // 2 days
$_SESSION["timeout"] = time() + $inactive;
return $response->withHeader("Location", "https://rohitpai.co.uk/editor/")->withStatus(302);
}
$response->getBody()->write(json_encode(array("error" => "Unauthorised")));
return $response->withStatus(401);
});
$app->post("/user/changePassword", function (Request $request, Response $response)
@ -217,4 +214,4 @@ class userRoutes implements routesInterface
return $response->withStatus(500);
});
}
}
}

View File

@ -84,6 +84,11 @@ article a::after {
margin-top: 1px;
}
article a.btn::before,
article a.btn::after {
display: none;
}
article a::before {
content: ' <';
margin-left: -0.5em;
@ -110,6 +115,27 @@ article h3:not(div.byLine > h3), .otherPosts h3 {
font-weight: bold;
}
article .media {
align-self: center;
}
article table td, article table th {
border: 1px solid #ddd;
padding: 8px;
}
article table tr:nth-child(even) {
background-color: #f2f2f2;
}
article table tr:hover {
background-color: #ddd;
}
article .table {
margin: 0;
}
aside.sideContent {
display: flex;
flex-direction: column;

View File

@ -8,7 +8,6 @@
@import "blogPosts.css";
@import "home.css";
@import "category.css";
@import "prism.css";
.policy {
display: flex;

View File

@ -1,9 +1,12 @@
/* PrismJS 1.29.0
https://prismjs.com/download.html#themes=prism-okaidia&languages=markup+css+clike+javascript+abap+abnf+actionscript+ada+agda+al+antlr4+apacheconf+apex+apl+applescript+aql+arduino+arff+armasm+arturo+asciidoc+aspnet+asm6502+asmatmel+autohotkey+autoit+avisynth+avro-idl+awk+bash+basic+batch+bbcode+bbj+bicep+birb+bison+bnf+bqn+brainfuck+brightscript+bro+bsl+c+csharp+cpp+cfscript+chaiscript+cil+cilkc+cilkcpp+clojure+cmake+cobol+coffeescript+concurnas+csp+cooklang+coq+crystal+css-extras+csv+cue+cypher+d+dart+dataweave+dax+dhall+diff+django+dns-zone-file+docker+dot+ebnf+editorconfig+eiffel+ejs+elixir+elm+etlua+erb+erlang+excel-formula+fsharp+factor+false+firestore-security-rules+flow+fortran+ftl+gml+gap+gcode+gdscript+gedcom+gettext+gherkin+git+glsl+gn+linker-script+go+go-module+gradle+graphql+groovy+haml+handlebars+haskell+haxe+hcl+hlsl+hoon+http+hpkp+hsts+ichigojam+icon+icu-message-format+idris+ignore+inform7+ini+io+j+java+javadoc+javadoclike+javastacktrace+jexl+jolie+jq+jsdoc+js-extras+json+json5+jsonp+jsstacktrace+js-templates+julia+keepalived+keyman+kotlin+kumir+kusto+latex+latte+less+lilypond+liquid+lisp+livescript+llvm+log+lolcode+lua+magma+makefile+markdown+markup-templating+mata+matlab+maxscript+mel+mermaid+metafont+mizar+mongodb+monkey+moonscript+n1ql+n4js+nand2tetris-hdl+naniscript+nasm+neon+nevod+nginx+nim+nix+nsis+objectivec+ocaml+odin+opencl+openqasm+oz+parigp+parser+pascal+pascaligo+psl+pcaxis+peoplecode+perl+php+phpdoc+php-extras+plant-uml+plsql+powerquery+powershell+processing+prolog+promql+properties+protobuf+pug+puppet+pure+purebasic+purescript+python+qsharp+q+qml+qore+r+racket+cshtml+jsx+tsx+reason+regex+rego+renpy+rescript+rest+rip+roboconf+robotframework+ruby+rust+sas+sass+scss+scala+scheme+shell-session+smali+smalltalk+smarty+sml+solidity+solution-file+soy+sparql+splunk-spl+sqf+sql+squirrel+stan+stata+iecst+stylus+supercollider+swift+systemd+t4-templating+t4-cs+t4-vb+tap+tcl+tt2+textile+toml+tremor+turtle+twig+typescript+typoscript+unrealscript+uorazor+uri+v+vala+vbnet+velocity+verilog+vhdl+vim+visual-basic+warpscript+wasm+web-idl+wgsl+wiki+wolfram+wren+xeora+xml-doc+xojo+xquery+yaml+yang+zig&plugins=line-numbers+autolinker+show-language+previewers+toolbar+match-braces+diff-highlight */
code[class*=language-],pre[class*=language-]{color:#f8f8f2;background:0 0;text-shadow:0 1px rgba(0,0,0,.3);font-family:Consolas,Monaco,'Andale Mono','Ubuntu Mono',monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto;border-radius:.3em}:not(pre)>code[class*=language-],pre[class*=language-]{background:#272822}:not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em;white-space:normal}.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#8292a2}.token.punctuation{color:#f8f8f2}.token.namespace{opacity:.7}.token.constant,.token.deleted,.token.property,.token.symbol,.token.tag{color:#f92672}.token.boolean,.token.number{color:#ae81ff}.token.attr-name,.token.builtin,.token.char,.token.inserted,.token.selector,.token.string{color:#a6e22e}.language-css .token.string,.style .token.string,.token.entity,.token.operator,.token.url,.token.variable{color:#f8f8f2}.token.atrule,.token.attr-value,.token.class-name,.token.function{color:#e6db74}.token.keyword{color:#66d9ef}.token.important,.token.regex{color:#fd971f}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}
https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript+abap+abnf+actionscript+ada+agda+al+antlr4+apacheconf+apex+apl+applescript+aql+arduino+arff+armasm+arturo+asciidoc+aspnet+asm6502+asmatmel+autohotkey+autoit+avisynth+avro-idl+awk+bash+basic+batch+bbcode+bbj+bicep+birb+bison+bnf+bqn+brainfuck+brightscript+bro+bsl+c+csharp+cpp+cfscript+chaiscript+cil+cilkc+cilkcpp+clojure+cmake+cobol+coffeescript+concurnas+csp+cooklang+coq+crystal+css-extras+csv+cue+cypher+d+dart+dataweave+dax+dhall+diff+django+dns-zone-file+docker+dot+ebnf+editorconfig+eiffel+ejs+elixir+elm+etlua+erb+erlang+excel-formula+fsharp+factor+false+firestore-security-rules+flow+fortran+ftl+gml+gap+gcode+gdscript+gedcom+gettext+gherkin+git+glsl+gn+linker-script+go+go-module+gradle+graphql+groovy+haml+handlebars+haskell+haxe+hcl+hlsl+hoon+http+hpkp+hsts+ichigojam+icon+icu-message-format+idris+ignore+inform7+ini+io+j+java+javadoc+javadoclike+javastacktrace+jexl+jolie+jq+jsdoc+js-extras+json+json5+jsonp+jsstacktrace+js-templates+julia+keepalived+keyman+kotlin+kumir+kusto+latex+latte+less+lilypond+liquid+lisp+livescript+llvm+log+lolcode+lua+magma+makefile+markdown+markup-templating+mata+matlab+maxscript+mel+mermaid+metafont+mizar+mongodb+monkey+moonscript+n1ql+n4js+nand2tetris-hdl+naniscript+nasm+neon+nevod+nginx+nim+nix+nsis+objectivec+ocaml+odin+opencl+openqasm+oz+parigp+parser+pascal+pascaligo+psl+pcaxis+peoplecode+perl+php+phpdoc+php-extras+plant-uml+plsql+powerquery+powershell+processing+prolog+promql+properties+protobuf+pug+puppet+pure+purebasic+purescript+python+qsharp+q+qml+qore+r+racket+cshtml+jsx+tsx+reason+regex+rego+renpy+rescript+rest+rip+roboconf+robotframework+ruby+rust+sas+sass+scss+scala+scheme+shell-session+smali+smalltalk+smarty+sml+solidity+solution-file+soy+sparql+splunk-spl+sqf+sql+squirrel+stan+stata+iecst+stylus+supercollider+swift+systemd+t4-templating+t4-cs+t4-vb+tap+tcl+tt2+textile+toml+tremor+turtle+twig+typescript+typoscript+unrealscript+uorazor+uri+v+vala+vbnet+velocity+verilog+vhdl+vim+visual-basic+warpscript+wasm+web-idl+wgsl+wiki+wolfram+wren+xeora+xml-doc+xojo+xquery+yaml+yang+zig&plugins=line-numbers+show-language+inline-color+previewers+unescaped-markup+toolbar+copy-to-clipboard+download-button+match-braces */
code[class*=language-],pre[class*=language-]{color:#000;background:0 0;text-shadow:0 1px #fff;font-family:Consolas,Monaco,'Andale Mono','Ubuntu Mono',monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}code[class*=language-] ::-moz-selection,code[class*=language-]::-moz-selection,pre[class*=language-] ::-moz-selection,pre[class*=language-]::-moz-selection{text-shadow:none;background:#b3d4fc}code[class*=language-] ::selection,code[class*=language-]::selection,pre[class*=language-] ::selection,pre[class*=language-]::selection{text-shadow:none;background:#b3d4fc}@media print{code[class*=language-],pre[class*=language-]{text-shadow:none}}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto}:not(pre)>code[class*=language-],pre[class*=language-]{background:#f5f2f0}:not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em;white-space:normal}.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#708090}.token.punctuation{color:#999}.token.namespace{opacity:.7}.token.boolean,.token.constant,.token.deleted,.token.number,.token.property,.token.symbol,.token.tag{color:#905}.token.attr-name,.token.builtin,.token.char,.token.inserted,.token.selector,.token.string{color:#690}.language-css .token.string,.style .token.string,.token.entity,.token.operator,.token.url{color:#9a6e3a;background:hsla(0,0%,100%,.5)}.token.atrule,.token.attr-value,.token.keyword{color:#07a}.token.class-name,.token.function{color:#dd4a68}.token.important,.token.regex,.token.variable{color:#e90}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}
pre[class*=language-].line-numbers{position:relative;padding-left:3.8em;counter-reset:linenumber}pre[class*=language-].line-numbers>code{position:relative;white-space:inherit}.line-numbers .line-numbers-rows{position:absolute;pointer-events:none;top:0;font-size:100%;left:-3.8em;width:3em;letter-spacing:-1px;border-right:1px solid #999;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.line-numbers-rows>span{display:block;counter-increment:linenumber}.line-numbers-rows>span:before{content:counter(linenumber);color:#999;display:block;padding-right:.8em;text-align:right}
.token a{color:inherit}
div.code-toolbar{position:relative}div.code-toolbar>.toolbar{position:absolute;z-index:10;top:.3em;right:.2em;transition:opacity .3s ease-in-out;opacity:0}div.code-toolbar:hover>.toolbar{opacity:1}div.code-toolbar:focus-within>.toolbar{opacity:1}div.code-toolbar>.toolbar>.toolbar-item{display:inline-block}div.code-toolbar>.toolbar>.toolbar-item>a{cursor:pointer}div.code-toolbar>.toolbar>.toolbar-item>button{background:0 0;border:0;color:inherit;font:inherit;line-height:normal;overflow:visible;padding:0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}div.code-toolbar>.toolbar>.toolbar-item>a,div.code-toolbar>.toolbar>.toolbar-item>button,div.code-toolbar>.toolbar>.toolbar-item>span{color:#bbb;font-size:.8em;padding:0 .5em;background:#f5f2f0;background:rgba(224,224,224,.2);box-shadow:0 2px 0 0 rgba(0,0,0,.2);border-radius:.5em}div.code-toolbar>.toolbar>.toolbar-item>a:focus,div.code-toolbar>.toolbar>.toolbar-item>a:hover,div.code-toolbar>.toolbar>.toolbar-item>button:focus,div.code-toolbar>.toolbar>.toolbar-item>button:hover,div.code-toolbar>.toolbar>.toolbar-item>span:focus,div.code-toolbar>.toolbar>.toolbar-item>span:hover{color:inherit;text-decoration:none}
span.inline-color-wrapper{background:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyIDIiPjxwYXRoIGZpbGw9ImdyYXkiIGQ9Ik0wIDBoMnYySDB6Ii8+PHBhdGggZmlsbD0id2hpdGUiIGQ9Ik0wIDBoMXYxSDB6TTEgMWgxdjFIMXoiLz48L3N2Zz4=);background-position:center;background-size:110%;display:inline-block;height:1.333ch;width:1.333ch;margin:0 .333ch;box-sizing:border-box;border:1px solid #fff;outline:1px solid rgba(0,0,0,.5);overflow:hidden}span.inline-color{display:block;height:120%;width:120%}
.prism-previewer,.prism-previewer:after,.prism-previewer:before{position:absolute;pointer-events:none}.prism-previewer,.prism-previewer:after{left:50%}.prism-previewer{margin-top:-48px;width:32px;height:32px;margin-left:-16px;z-index:10;opacity:0;-webkit-transition:opacity .25s;-o-transition:opacity .25s;transition:opacity .25s}.prism-previewer.flipped{margin-top:0;margin-bottom:-48px}.prism-previewer:after,.prism-previewer:before{content:'';position:absolute;pointer-events:none}.prism-previewer:before{top:-5px;right:-5px;left:-5px;bottom:-5px;border-radius:10px;border:5px solid #fff;box-shadow:0 0 3px rgba(0,0,0,.5) inset,0 0 10px rgba(0,0,0,.75)}.prism-previewer:after{top:100%;width:0;height:0;margin:5px 0 0 -7px;border:7px solid transparent;border-color:rgba(255,0,0,0);border-top-color:#fff}.prism-previewer.flipped:after{top:auto;bottom:100%;margin-top:0;margin-bottom:5px;border-top-color:rgba(255,0,0,0);border-bottom-color:#fff}.prism-previewer.active{opacity:1}.prism-previewer-angle:before{border-radius:50%;background:#fff}.prism-previewer-angle:after{margin-top:4px}.prism-previewer-angle svg{width:32px;height:32px;-webkit-transform:rotate(-90deg);-moz-transform:rotate(-90deg);-ms-transform:rotate(-90deg);-o-transform:rotate(-90deg);transform:rotate(-90deg)}.prism-previewer-angle[data-negative] svg{-webkit-transform:scaleX(-1) rotate(-90deg);-moz-transform:scaleX(-1) rotate(-90deg);-ms-transform:scaleX(-1) rotate(-90deg);-o-transform:scaleX(-1) rotate(-90deg);transform:scaleX(-1) rotate(-90deg)}.prism-previewer-angle circle{fill:transparent;stroke:#2d3438;stroke-opacity:.9;stroke-width:32;stroke-dasharray:0,500}.prism-previewer-gradient{background-image:linear-gradient(45deg,#bbb 25%,transparent 25%,transparent 75%,#bbb 75%,#bbb),linear-gradient(45deg,#bbb 25%,#eee 25%,#eee 75%,#bbb 75%,#bbb);background-size:10px 10px;background-position:0 0,5px 5px;width:64px;margin-left:-32px}.prism-previewer-gradient:before{content:none}.prism-previewer-gradient div{position:absolute;top:-5px;left:-5px;right:-5px;bottom:-5px;border-radius:10px;border:5px solid #fff;box-shadow:0 0 3px rgba(0,0,0,.5) inset,0 0 10px rgba(0,0,0,.75)}.prism-previewer-color{background-image:linear-gradient(45deg,#bbb 25%,transparent 25%,transparent 75%,#bbb 75%,#bbb),linear-gradient(45deg,#bbb 25%,#eee 25%,#eee 75%,#bbb 75%,#bbb);background-size:10px 10px;background-position:0 0,5px 5px}.prism-previewer-color:before{background-color:inherit;background-clip:padding-box}.prism-previewer-easing{margin-top:-76px;margin-left:-30px;width:60px;height:60px;background:#333}.prism-previewer-easing.flipped{margin-bottom:-116px}.prism-previewer-easing svg{width:60px;height:60px}.prism-previewer-easing circle{fill:#2d3438;stroke:#fff}.prism-previewer-easing path{fill:none;stroke:#fff;stroke-linecap:round;stroke-width:4}.prism-previewer-easing line{stroke:#fff;stroke-opacity:.5;stroke-width:2}@-webkit-keyframes prism-previewer-time{0%{stroke-dasharray:0,500;stroke-dashoffset:0}50%{stroke-dasharray:100,500;stroke-dashoffset:0}100%{stroke-dasharray:0,500;stroke-dashoffset:-100}}@-o-keyframes prism-previewer-time{0%{stroke-dasharray:0,500;stroke-dashoffset:0}50%{stroke-dasharray:100,500;stroke-dashoffset:0}100%{stroke-dasharray:0,500;stroke-dashoffset:-100}}@-moz-keyframes prism-previewer-time{0%{stroke-dasharray:0,500;stroke-dashoffset:0}50%{stroke-dasharray:100,500;stroke-dashoffset:0}100%{stroke-dasharray:0,500;stroke-dashoffset:-100}}@keyframes prism-previewer-time{0%{stroke-dasharray:0,500;stroke-dashoffset:0}50%{stroke-dasharray:100,500;stroke-dashoffset:0}100%{stroke-dasharray:0,500;stroke-dashoffset:-100}}.prism-previewer-time:before{border-radius:50%;background:#fff}.prism-previewer-time:after{margin-top:4px}.prism-previewer-time svg{width:32px;height:32px;-webkit-transform:rotate(-90deg);-moz-transform:rotate(-90deg);-ms-transform:rotate(-90deg);-o-transform:rotate(-90deg);transform:rotate(-90deg)}.prism-previewer-time circle{fill:transparent;stroke:#2d3438;stroke-opacity:.9;stroke-width:32;stroke-dasharray:0,500;stroke-dashoffset:0;-webkit-animation:prism-previewer-time linear infinite 3s;-moz-animation:prism-previewer-time linear infinite 3s;-o-animation:prism-previewer-time linear infinite 3s;animation:prism-previewer-time linear infinite 3s}
[class*=lang-] script[type='text/plain'],[class*=language-] script[type='text/plain'],script[type='text/plain'][class*=lang-],script[type='text/plain'][class*=language-]{display:block;font:100% Consolas,Monaco,monospace;white-space:pre;overflow:auto}
.token.punctuation.brace-hover,.token.punctuation.brace-selected{outline:solid 1px}.rainbow-braces .token.punctuation.brace-level-1,.rainbow-braces .token.punctuation.brace-level-5,.rainbow-braces .token.punctuation.brace-level-9{color:#e50;opacity:1}.rainbow-braces .token.punctuation.brace-level-10,.rainbow-braces .token.punctuation.brace-level-2,.rainbow-braces .token.punctuation.brace-level-6{color:#0b3;opacity:1}.rainbow-braces .token.punctuation.brace-level-11,.rainbow-braces .token.punctuation.brace-level-3,.rainbow-braces .token.punctuation.brace-level-7{color:#26f;opacity:1}.rainbow-braces .token.punctuation.brace-level-12,.rainbow-braces .token.punctuation.brace-level-4,.rainbow-braces .token.punctuation.brace-level-8{color:#e0e;opacity:1}
pre.diff-highlight>code .token.deleted:not(.prefix),pre>code.diff-highlight .token.deleted:not(.prefix){background-color:rgba(255,0,0,.1);color:inherit;display:block}pre.diff-highlight>code .token.inserted:not(.prefix),pre>code.diff-highlight .token.inserted:not(.prefix){background-color:rgba(0,255,128,.1);color:inherit;display:block}
/*gruvbox light*/
code[class*=language-],pre[class*=language-]{color:#3c3836;font-family:Consolas,Monaco,"Andale Mono",monospace;direction:ltr;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}code[class*=language-] ::-moz-selection,code[class*=language-]::-moz-selection,pre[class*=language-] ::-moz-selection,pre[class*=language-]::-moz-selection{color:#282828;background:#a89984}code[class*=language-] ::selection,code[class*=language-]::selection,pre[class*=language-] ::selection,pre[class*=language-]::selection{color:#282828;background:#a89984}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto}:not(pre)>code[class*=language-],pre[class*=language-]{background:#f9f5d7}:not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em}.token.attr-name,.token.attr-value,.token.attr-value .punctuation,.token.cdata,.token.comment,.token.operator,.token.prolog,.token.punctuation{color:#7c6f64}.token.atrule,.token.boolean,.token.constant,.token.delimiter,.token.important,.token.keyword,.token.property,.token.selector,.token.variable{color:#9d0006}.token.builtin,.token.doctype,.token.function,.token.tag,.token.tag .punctuation{color:#b57614}.token.entity,.token.number,.token.symbol{color:#8f3f71}.token.char,.token.string,.token.url{color:#797403}.token.url{text-decoration:underline}.token.regex{background:#797403}.token.bold{font-weight:700}.token.italic{font-style:italic}.token.inserted{background:#7c6f64}.token.deleted{background:#9d0006}

View File

@ -15,6 +15,7 @@
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="language" content="English">
<meta name="author" content="Rohit Pai">
<link rel="stylesheet" href="/blog/css/prism.css">
<link rel="stylesheet" href="/blog/css/main.css">
<script src="https://kit.fontawesome.com/ed3c25598e.js" crossorigin="anonymous"></script>
<script type='text/javascript'
@ -100,6 +101,7 @@
</footer>
<script src="/js/typewriter.js"></script>
<script src="/blog/js/prism.js"></script>
<script src="/blog/js/index.js"></script>
<script id="dsq-count-scr" src="https://rohitpaiportfolio.disqus.com/count.js" async></script>
</body>

View File

@ -589,6 +589,7 @@ async function loadIndividualPost(title)
s.setAttribute('data-timestamp', +new Date());
d.body.appendChild(s);
})();
Prism.highlightAll();
});
});
}

File diff suppressed because one or more lines are too long

View File

@ -120,4 +120,4 @@ div.message.hidden {
div.message button:hover {
text-shadow: -1px 2px var(--mutedBlack);
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -858,6 +858,31 @@ function createEditors(...ids)
{language: 'zephir', label: 'Zephir'},
],
},
mediaEmbed: {
previewsInData: true,
providers: [
{
name: 'youtube',
url: [
/^(?:m\.)?youtube\.com\/watch\?v=([\w-]+)(?:&t=(\d+))?/,
/^(?:m\.)?youtube\.com\/v\/([\w-]+)(?:\?t=(\d+))?/,
/^youtube\.com\/embed\/([\w-]+)(?:\?start=(\d+))?/,
/^youtu\.be\/([\w-]+)(?:\?t=(\d+))?/,
],
html: match =>
{
const id = match[1];
const time = match[2];
return (
`<iframe width="560" height="315" style="text-align:center;" src="https://www.youtube.com/embed/${id}${time ? `?start=${time}` : ''}" ` +
'frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen>' +
'</iframe>'
);
},
},
],
},
}).then(CKEditor =>
{
editors[id] = CKEditor;
@ -1197,11 +1222,11 @@ function updateProjectItem(id, e)
{
e.preventDefault();
let data = {}
data["title"] = document.querySelector(`#title${id}`).value;
data["isMainProject"] = document.querySelector(`#isMainProject${id}`).checked ? "true" : "false";
data["information"] = document.querySelector(`#info${id}`).value;
data["projectLink"] = document.querySelector(`#viewProj${id}`).value;
data["gitLink"] = document.querySelector(`#git${id}`).value;
data['title'] = document.querySelector(`#title${id}proj`).value;
data['isMainProject'] = document.querySelector(`#isMainProject${id}proj`).checked ? 'true' : 'false';
data['information'] = document.querySelector(`#info${id}proj`).value;
data['projectLink'] = document.querySelector(`#viewProj${id}proj`).value;
data['gitLink'] = document.querySelector(`#git${id}proj`).value;
let imgData = new FormData();
imgData.append("img", document.querySelector(`#img${id}`).files[0]);

View File

@ -32,6 +32,7 @@
<li><a href="/blog" class="textShadow link">blog</a></li>
</ul>
</nav>
<header>
<div>
<h1>full stack developer</h1>
@ -108,7 +109,7 @@
</a>
</div>
<div>
<a href="#">
<a href="https://rohitpai.co.uk/blog">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path d="M15.5 14.625c0 .484-.387.875-.864.875h-5.273c-.477 0-.863-.392-.863-.875s.387-.875.863-.875h5.272c.478 0 .865.391.865.875zm-6.191-4.375h2.466c.448 0 .809-.392.809-.875s-.361-.875-.81-.875h-2.465c-.447 0-.809.392-.809.875s.362.875.809.875zm14.691 1.75c0 6.627-5.373 12-12 12s-12-5.373-12-12 5.373-12 12-12 12 5.373 12 12zm-5-1.039c0-.383-.311-.692-.691-.692h-1.138c-.583 0-.69-.446-.69-.996-.001-2.36-1.91-4.273-4.265-4.273h-2.952c-2.355 0-4.264 1.913-4.264 4.272v5.455c0 2.36 1.909 4.273 4.264 4.273h5.474c2.353 0 4.262-1.913 4.262-4.272v-3.767z"/>
</svg>
@ -173,15 +174,16 @@
</form>
</div>
</section>
<footer class="flexRow">
<div class="spacer"></div>
<p>&copy; <span id="year"></span> Rohit Pai all rights reserved</p>
<div class="button">
<button id="goBackToTop"><i class="fa-solid fa-chevron-up"></i></button>
</div>
</footer>
</main>
<footer class="flexRow">
<div class="spacer"></div>
<p>&copy; <span id="year"></span> Rohit Pai all rights reserved</p>
<div class="button">
<button id="goBackToTop"><i class="fa-solid fa-chevron-up"></i></button>
</div>
</footer>
<script src="js/index.js"></script>
<script src="js/typewriter.js"></script>
</body>