<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[Todd Smith-Salter]]></title><description><![CDATA[Todd Smith-Salter]]></description><link>https://toddsmithsalter.com/</link><image><url>https://toddsmithsalter.com/favicon.png</url><title>Todd Smith-Salter</title><link>https://toddsmithsalter.com/</link></image><generator>Ghost 3.40</generator><lastBuildDate>Sat, 07 Mar 2026 15:29:35 GMT</lastBuildDate><atom:link href="https://toddsmithsalter.com/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[The Simple Framework for Mastering Uncomfortable Conversations with Jefferson Fisher]]></title><description><![CDATA[<p>What an incredible, informative, and inspiration discussion. Well worth the 1+ hour watch time. All leaders will have a difficult conversation with team members and the frameworks discussed in this video are incredibly useful, but more importantly, simple to implement with practice.</p><figure class="kg-card kg-embed-card"><iframe width="356" height="200" src="https://www.youtube.com/embed/YB0aPYsotfc?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen title="Trial Lawyer: The Simple Framework for Mastering Uncomfortable Conversations (Jefferson Fisher)"></iframe></figure>]]></description><link>https://toddsmithsalter.com/the-simple-framework-for-mastering-uncomfortable-conversations/</link><guid isPermaLink="false">68b9f22a376cde556310468b</guid><dc:creator><![CDATA[Todd Smith-Salter]]></dc:creator><pubDate>Thu, 04 Sep 2025 20:12:56 GMT</pubDate><content:encoded><![CDATA[<p>What an incredible, informative, and inspiration discussion. Well worth the 1+ hour watch time. All leaders will have a difficult conversation with team members and the frameworks discussed in this video are incredibly useful, but more importantly, simple to implement with practice.</p><figure class="kg-card kg-embed-card"><iframe width="356" height="200" src="https://www.youtube.com/embed/YB0aPYsotfc?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen title="Trial Lawyer: The Simple Framework for Mastering Uncomfortable Conversations (Jefferson Fisher)"></iframe></figure>]]></content:encoded></item><item><title><![CDATA[Should I be scared?]]></title><description><![CDATA[<p>I don't know what to think about the AI landscape. Large-language models and generative art speak to the ingenuity of the human mind. However, the idea that most content on the web is generated rather than original is troubling.</p><p>It could be said that all content is "generated". Unoriginal. Derivative.</p>]]></description><link>https://toddsmithsalter.com/should-i-be-scared/</link><guid isPermaLink="false">659470f5c43f0304d32fa6c1</guid><dc:creator><![CDATA[Todd Smith-Salter]]></dc:creator><pubDate>Tue, 02 Jan 2024 20:31:42 GMT</pubDate><content:encoded><![CDATA[<p>I don't know what to think about the AI landscape. Large-language models and generative art speak to the ingenuity of the human mind. However, the idea that most content on the web is generated rather than original is troubling.</p><p>It could be said that all content is "generated". Unoriginal. Derivative. All human thought and creativity has been trained into us by the environment around us from infancy to adulthood. A defeatist attitude would agree this sentiment.</p><p>I truely believe there is real creativity and original thougth in this world. That a loving creator gave us, His creations, free thought and willing minds to be creative and populate the world with creative material.</p><p>The dawn of actually intelligent Artificial Intelligence doesn't mean that creativity goes away, but it does mean the spaces where creativity has been displayed for the past several decades are diminishing. Where will real art and creative passion projects be hung for the world to see?</p>]]></content:encoded></item><item><title><![CDATA[Breaking Out of a Central Wrapper]]></title><description><![CDATA[<p>A good reminder of 5 (FIVE!!!) methods from Michelle Barker to go full-width when all content is contained in a central wrapper.</p><p>🔗 <a href="https://css-irl.info/breaking-out-of-a-central-wrapper/">https://css-irl.info/breaking-out-of-a-central-wrapper/</a></p>]]></description><link>https://toddsmithsalter.com/breaking-out-of-a-central-wrapper/</link><guid isPermaLink="false">62d18742c43f0304d32fa69d</guid><category><![CDATA[css]]></category><dc:creator><![CDATA[Todd Smith-Salter]]></dc:creator><pubDate>Fri, 15 Jul 2022 15:31:47 GMT</pubDate><content:encoded><![CDATA[<p>A good reminder of 5 (FIVE!!!) methods from Michelle Barker to go full-width when all content is contained in a central wrapper.</p><p>🔗 <a href="https://css-irl.info/breaking-out-of-a-central-wrapper/">https://css-irl.info/breaking-out-of-a-central-wrapper/</a></p>]]></content:encoded></item><item><title><![CDATA[Easy JSON API Responses with Laravel]]></title><description><![CDATA[<p><a href="https://laravel.com/">Laravel</a> has evolved so much since I last laid hands on in over a year-and-a-half ago. <a href="https://laravel.com/docs/8.x/eloquent-resources">Eloquent API Resources</a> are a massive boost to those of us looking to easily hammer out standardized JSON API responses. While these are not fully-spec compliant <a href="https://jsonapi.org/">{json:api}</a> responses, they're pretty darn close and</p>]]></description><link>https://toddsmithsalter.com/json-api-responses-with-laravel/</link><guid isPermaLink="false">5ffe174cc43f0304d32fa5d6</guid><category><![CDATA[laravel]]></category><category><![CDATA[jsonapi]]></category><dc:creator><![CDATA[Todd Smith-Salter]]></dc:creator><pubDate>Tue, 12 Jan 2021 22:07:51 GMT</pubDate><content:encoded><![CDATA[<p><a href="https://laravel.com/">Laravel</a> has evolved so much since I last laid hands on in over a year-and-a-half ago. <a href="https://laravel.com/docs/8.x/eloquent-resources">Eloquent API Resources</a> are a massive boost to those of us looking to easily hammer out standardized JSON API responses. While these are not fully-spec compliant <a href="https://jsonapi.org/">{json:api}</a> responses, they're pretty darn close and good enough for most use cases.</p><p>Simply put, an API Resource consumes a database query in the form of a model and spits out structured JSON. In the usual Laravel way, API Resources are easily customized.</p><p><em>Heads up: this is based on Laravel 8.x. and may not work in previous versions.</em></p><h2 id="create-a-resource-for-a-single-object">Create a Resource for a Single Object</h2><p>So, let's say I want to query a single user. First I'll start by using <em>artistan</em> to create the Resource class file.</p><pre><code class="language-bash">php artisan make:resource UserResource</code></pre><p>Then in the <code>toArray($request)</code> method, I'll return an array of what I want to expose to the API consumer. This is great, as I can abstract the model properties away from the response and do some basic serialization before responding, if desired.</p><pre><code class="language-php">public function toArray($request)
{
    return [
        'id' =&gt; $this-&gt;id,
        'name' =&gt; $this-&gt;name,
        'email' =&gt; $this-&gt;email,
        'created_at' =&gt; $this-&gt;created_at,
        'updated_at' =&gt; $this-&gt;updated_at,
    ];
}</code></pre><p>Now I can simply return the Resource from the controller. By default, the array will be wrapped in a <code>data</code> key. I recommend leaving this setting as is but it can be overridden <a href="https://laravel.com/docs/8.x/eloquent-resources#data-wrapping">as per the documentation</a>.</p><pre><code class="language-php">use App\Http\Resources\UserCollection;
use App\Models\User;

Route::get('/users', function () {
    return new UserCollection(User::all());
});</code></pre><p>The object returned will look similar to the following.</p><pre><code class="language-json">{
    data: {
    	id: 1,
        name: 'Luke Skywalker',
        email: 'l.skywalker@jedi.org',
        created_at: 'timestamp',
        updated_at: 'timestamp'
    }
}</code></pre><h2 id="return-a-collection">Return a Collection</h2><p>The <code>JsonResource</code> class has a static <code>collection</code> method to return an array of Resources, or in my case, Users. This is so dang easy I want to weep for joy.</p><pre><code class="language-php">use App\Http\Resources\UserResource;
use App\Models\User;

Route::get('/users', function () {
    return UserResource::collection(User::all());
});</code></pre><p>This returns an array of Users in the <code>data</code> key.</p><pre><code class="language-json">{
    data: [
        {
            id: 1,
            name: 'Luke Skywalker',
            email: 'l.skywalker@jedi.org',
            created_at: 'timestamp',
            updated_at: 'timestamp'
        },
        {
            id: 2,
            name: 'Leia Organa',
            email: 'l.organa@rebelalliance.org',
            created_at: 'timestamp',
            updated_at: 'timestamp'
        },
        ...
    ]
}</code></pre><p>More complex customizations can be done by creating a <code>UserCollection</code> resource, which Laravel is smart enough to proxy to a collection of <code>UserResource</code> instances. </p><h2 id="other-goodies">Other Goodies</h2><p>Eloquent API Resources also makes these features seem a breeze to implement:</p><ul><li><a href="https://laravel.com/docs/8.x/eloquent-resources#pagination">Pagination</a></li><li><a href="https://laravel.com/docs/8.x/eloquent-resources#conditional-attributes">Conditional Attributes</a></li><li><a href="https://laravel.com/docs/8.x/eloquent-resources#relationships">Embedded Relationships</a></li><li><a href="https://laravel.com/docs/8.x/eloquent-resources#conditional-relationships">Conditional Relationships</a></li></ul><p><a href="https://laravel.com/docs/8.x/eloquent-resources">View the full documentation</a> for the full details of Eloquent API Resources.</p>]]></content:encoded></item><item><title><![CDATA[Year In Review: 2020]]></title><description><![CDATA[A rundown of my year in 2020.]]></description><link>https://toddsmithsalter.com/year-in-review-2020/</link><guid isPermaLink="false">5ff385b1c43f0304d32fa510</guid><category><![CDATA[review]]></category><category><![CDATA[personal]]></category><dc:creator><![CDATA[Todd Smith-Salter]]></dc:creator><pubDate>Mon, 04 Jan 2021 21:55:52 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1604440977273-f22b2fa6ea5b?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MXwxMTc3M3wwfDF8c2VhcmNofDF8fDIwMjB8ZW58MHx8fA&amp;ixlib=rb-1.2.1&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<h2 id="review">Review</h2><h3 id="what-went-well">What Went Well</h3><h4 id="vocation">Vocation</h4><img src="https://images.unsplash.com/photo-1604440977273-f22b2fa6ea5b?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=MXwxMTc3M3wwfDF8c2VhcmNofDF8fDIwMjB8ZW58MHx8fA&ixlib=rb-1.2.1&q=80&w=2000" alt="Year In Review: 2020"><p>The COVID-19 pandemic threw a wrench in everyone’s years. Thankfully, my job continued for most of the year, in-person, no less. Sadly, my role at NTL Pipelines ended in November but I am thankful for my time there.</p><h4 id="spiritual">Spiritual</h4><p>Stepped up my personal accountability game by making habits to connect with my mates regularly throughout each week.</p><p>Restarted regular therapy in June and dug into a lot of hurts and wounds from my past. I have a lot of hope for a mentally healthy future.</p><h3 id="what-didn-t-go-well">What Didn't Go Well</h3><h4 id="personal-health">Personal Health</h4><p>As a result of my 72-hour-a-week role starting in July 2019, I fell completely off the exercise wagon and didn’t get back into it until well into June. Since then, I’ve run 2-3 times most weeks.</p><p>Eating healthy is another story. My sweet tooth became a monster in 2020 and I didn’t do much to curb it. I’ve felt most healthy when eliminating sugar from my diet and getting back to that spot would be wonderful.</p><p>I gained 10 lbs since last year due to the poor eating and little exercise. Would like to get back to my peak running weight of around 175 lbs.</p><h4 id="relationships">Relationships</h4><p>I let people down this year. Especially my wife. I’ve always struggled to communicate clearly and at opportune times, often holding back what I’m truly feeling. My poor sense of security and personal value means I hold onto my feelings out of fear of a negative response. It’s a vicious cycle I want to get out of with the help of God and my therapist.</p><h4 id="finances">Finances</h4><p>I had a good job, which paid the bills and more. My wife and I have struggled to talk the same language about finances over the years and haven’t been able to make a clear budget, not for lack of trying. We’re still living within our means and not buying excessive material possessions. However, if we are to be stewards of what we’ve been given, keeping ourselves accountable and saving to give away will be important.</p><h3 id="new-emerging-opportunities">New Emerging Opportunities</h3><p>My role ending at NTL means I have the opportunity to start over in a role better suited to my strengths and to our lifestyle. NTL was great but the hours (50-72 each week) were excessive and led to burn out and contributed to my poor personal health.</p><p>I’m excited to explore opportunities in the web development space. I spent the month of December 2020 getting back into javascript (<a href="https://reactjs.org/">React</a>, <a href="https://nextjs.org/">NextJS</a>) and <a href="https://www.php.net/">php</a> (<a href="https://laravel.com/">Laravel</a>). I’m looking forward to finding a great home for my technical expertise.</p><h2 id="music">Music</h2><h3 id="album-of-the-year">Album of the Year</h3><p>2020 and my AOTY is from 2006...living in the past, haha. This is such a great album and gets me going every time I listen to it. Great for when I'm in the flow.</p><figure class="kg-card kg-embed-card"><iframe width="300" height="380" allowtransparency="true" frameborder="0" allow="encrypted-media" title="Spotify Embed: Mutemath" src="https://open.spotify.com/embed/album/4LDhNGy31pPuvV4cPrTpqF?si=SvkbEsbfT9iyPOAW7DtSow"></iframe></figure><h3 id="track-of-the-year">Track of the Year</h3><figure class="kg-card kg-embed-card"><iframe width="300" height="380" allowtransparency="true" frameborder="0" allow="encrypted-media" title="Spotify Embed: Chaos" src="https://open.spotify.com/embed/track/4PnMSkoydTEsZaIpcRZ4lT?si=SVnBrVKBT6C3ZhWJqf-Pjw"></iframe></figure><h3 id="favs">Favs</h3><figure class="kg-card kg-embed-card"><iframe width="300" height="380" allowtransparency="true" frameborder="0" allow="encrypted-media" title="Spotify Embed: 2020 Favs" src="https://open.spotify.com/embed/playlist/2WJ9UXckgOBKcelTCW26hc?si=xjFqd1ElROSO7YKp55uspQ"></iframe></figure><h2 id="games">Games</h2><h3 id="game-of-the-year">Game of the Year</h3><p>I played the snot out of <a href="https://www.nintendo.com/games/detail/the-legend-of-zelda-breath-of-the-wild-switch/">Breath of the Wild</a>, finally wrapping up a 300 hour play-through in December. Loved it so much I've started a Master Mode play-through, which is stinking hard! Died at the first bokoblin I met. 😱</p><figure class="kg-card kg-image-card"><img src="https://toddsmithsalter.com/content/images/2021/01/the-legend-of-zelda-breath-of-the-wild-switch-hero.jpg" class="kg-image" alt="Year In Review: 2020" srcset="https://toddsmithsalter.com/content/images/size/w600/2021/01/the-legend-of-zelda-breath-of-the-wild-switch-hero.jpg 600w, https://toddsmithsalter.com/content/images/size/w1000/2021/01/the-legend-of-zelda-breath-of-the-wild-switch-hero.jpg 1000w, https://toddsmithsalter.com/content/images/size/w1600/2021/01/the-legend-of-zelda-breath-of-the-wild-switch-hero.jpg 1600w, https://toddsmithsalter.com/content/images/2021/01/the-legend-of-zelda-breath-of-the-wild-switch-hero.jpg 1920w" sizes="(min-width: 720px) 720px"></figure><h3 id="runner-up">Runner Up</h3><p>I only just started playing <a href="https://store.steampowered.com/app/1172380/STAR_WARS_Jedi_Fallen_Order/">STAR WARS Jedi: Fallen Order</a> but man, is this game beautiful. I've only scratched the surface but this game feels so immersive. It's not open world, very linear, but it's a great change of pace from BotW's freedom. Sometimes, I just want a game to tell me what's next.</p><figure class="kg-card kg-image-card"><img src="https://toddsmithsalter.com/content/images/2021/01/jedi-fallen-order-key-art-tall.jpg" class="kg-image" alt="Year In Review: 2020" srcset="https://toddsmithsalter.com/content/images/size/w600/2021/01/jedi-fallen-order-key-art-tall.jpg 600w, https://toddsmithsalter.com/content/images/size/w1000/2021/01/jedi-fallen-order-key-art-tall.jpg 1000w, https://toddsmithsalter.com/content/images/2021/01/jedi-fallen-order-key-art-tall.jpg 1536w" sizes="(min-width: 720px) 720px"></figure><h2 id="film-television">Film + Television</h2><p>I like watching movies and television shows, especially in the era where one can watch an entire season/series in a few days. I read most of The Expanse book series this year and paired it with watching the excellent first 4 seasons of <a href="https://www.imdb.com/title/tt3230854/">the television show</a>. I'd have to say, the only Amazon backed season, season four, was one of the better produced shows I've seen in a long time, especially all the sequences on Ilus.</p><figure class="kg-card kg-image-card"><img src="https://toddsmithsalter.com/content/images/2021/01/The-Expanse.jpg" class="kg-image" alt="Year In Review: 2020" srcset="https://toddsmithsalter.com/content/images/size/w600/2021/01/The-Expanse.jpg 600w, https://toddsmithsalter.com/content/images/size/w1000/2021/01/The-Expanse.jpg 1000w, https://toddsmithsalter.com/content/images/2021/01/The-Expanse.jpg 1280w" sizes="(min-width: 720px) 720px"></figure><h2 id="books">Books</h2><p>I read/listened to a lot of books this year. There's a distinct theme of science-fiction and fantasy.</p><ul><li><em>Saturn Run</em> by John Sandford</li><li><em>The Shadow of What Was Lost</em> by James Islington</li><li><em>An Echo of Things To Come</em> by James Islington</li><li><em>An Astronaut’s Guide to Life on Earth</em> by Chris Hadfield</li><li><em>Dune</em> by Frank Herbert</li><li><em>Five Feet Apart</em> by Rachael Lippincott</li><li><em>Pretty Girls</em> by Karin Slaughter</li><li><em>The Burning Sky</em> by Sherry Thomas</li><li><em>The Perilous Sea</em> by Sherry Thomas</li><li><em>The Immortal Heights</em> by Sherry Thomas</li><li><em>The Firebird Trilogy</em> by Kathy Tyers</li><li><em>Leviathan Wakes (The Expanse, 1)</em> by James S.A. Corey</li><li><em>Caliban’s War (The Expanse, 2)</em> by James S.A. Corey</li><li><em>The Calculating Stars</em> by Mary Robinette Kowal</li><li><em>Little House On The Prairie</em> by Laura Ingalls Wilder (re-read)</li><li><em>The Oracle Year</em> by Charles Soule</li><li><em>Gods of Risk (The Expanse, 2.5)</em> by James S.A. Corey</li><li><em>Abaddon’s Gate (The Expanse, 3)</em> by James S.A. Corey</li><li><em>Cibola Burn (The Expanse, 4)</em> by James S.A. Corey</li><li><em>Nemesis Games (The Expanse, 5)</em> by James S.A. Corey</li><li><em>The Vital Abyss (The Expanse, 5.5)</em> by James S.A. Corey</li><li><em>Babylon’s Ashes (The Expanse, 6)</em> by James S.A. Corey</li><li><em>Strange Dogs (The Expanse, 6.5)</em> by James S.A. Corey</li><li><em>Persepolis Rising (The Expanse 7)</em> by James S.A. Corey</li><li><em>Tiamat’s Wrath (The Expanse 8) </em>by James S.A. Corey</li><li><em>On the Banks of Plum Creek</em> by Laura Ingalls Wilder (re-read)</li><li><em>The Way of Kings</em> by Brandon Sanderson (re-read)</li></ul><p>I'd love to see what others are reading. Connect with me on <a href="https://www.goodreads.com/user/show/48395864-todd-smith-salter">Goodreads</a>.</p>]]></content:encoded></item><item><title><![CDATA[Getting Started with Laravel Sanctum]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p><em>Update on 01/06/2021: Added links to some helpful articles.</em></p>
<hr>
<p>Laravel Sanctum is a slim authentication system for Single Page Applications that don't need the full-meal-deal of an OAuth2 implementation. Sanctum protects an API from Cross Site Forgery Requests by setting a browser cookie and checking for the cookie</p>]]></description><link>https://toddsmithsalter.com/getting-started-with-laravel-sanctum/</link><guid isPermaLink="false">5fe3704ac43f0304d32fa48b</guid><category><![CDATA[note-to-self]]></category><category><![CDATA[laravel]]></category><category><![CDATA[development]]></category><dc:creator><![CDATA[Todd Smith-Salter]]></dc:creator><pubDate>Wed, 23 Dec 2020 23:46:40 GMT</pubDate><media:content url="https://toddsmithsalter.com/content/images/2020/12/All_c0525fe15a8bd68c9fbd762831ef9959_2000.jpg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://toddsmithsalter.com/content/images/2020/12/All_c0525fe15a8bd68c9fbd762831ef9959_2000.jpg" alt="Getting Started with Laravel Sanctum"><p><em>Update on 01/06/2021: Added links to some helpful articles.</em></p>
<hr>
<p>Laravel Sanctum is a slim authentication system for Single Page Applications that don't need the full-meal-deal of an OAuth2 implementation. Sanctum protects an API from Cross Site Forgery Requests by setting a browser cookie and checking for the cookie (or token) on request to ensure requests are coming from approved requesters, be it a first-party SPA or mobile application. It should be paired with a user authentication system.</p>
<p>The majority of this article is a concise summary of what's in the official documentation. If you need more details, follow the link below.</p>
<p><strong>Official Documentation:</strong> <a href="https://laravel.com/docs/8.x/sanctum">https://laravel.com/docs/8.x/sanctum</a></p>
<p><strong>Other helpful sources:</strong></p>
<ul>
<li><a href="https://redfern.dev/articles/authentication-laravel-sanctum-fortify-for-an-spa/">RedfernDev: Authentication Using Laravel Sanctum &amp; Fortify for an SPA</a></li>
<li><a href="https://www.youtube.com/watch?v=QYJKp1e71xs">Laravel Fortify SPA Authentication with Laravel Sanctum without Jetstream</a></li>
<li><a href="https://swiftmade.co/blog/2020-06-22-working-with-laravel-sanctum-in-paw">Swiftmade: Working with Laravel Sanctum in Paw</a>
<ul>
<li><strong>Gotcha:</strong> ensure you add a Referer header with the url pointing to your SPA url, which should match a value in the SANCTUMSTATEFULDOMAINS environment variable.</li>
</ul>
</li>
<li><a href="https://laravel-news.com/using-sanctum-to-authenticate-a-react-spa">Laravel News: Using Sanctum to authenticate a React SPA</a></li>
</ul>
<h2 id="quotesfromthedocs">Quotes from the Docs</h2>
<blockquote>
<p>&quot;Laravel Sanctum provides a featherweight authentication system for SPAs (single page applications), mobile applications, and simple, token based APIs.&quot;</p>
</blockquote>
<blockquote>
<p>&quot;Laravel Sanctum is only concerned with managing API tokens and authenticating existing users using session cookies or tokens. Sanctum does not provide any routes that handle user registration, password reset, etc.&quot;</p>
</blockquote>
<blockquote>
<p>&quot;When Sanctum examines an incoming HTTP request, it will first check for an authentication cookie and, if none is present, Sanctum will then examine the Authorization header for a valid API token.&quot;</p>
</blockquote>
<h2 id="installation">Installation</h2>
<p>Go to the project folder in terminal and add the Sanctum package with composer.</p>
<pre><code class="language-shell">composer require laravel/sanctum
</code></pre>
<p>Publish the config and migration files.</p>
<pre><code class="language-shell">php artisan vendor:publish --provider=&quot;Laravel\Sanctum\SanctumServiceProvider&quot;
</code></pre>
<p>Then run migrations.</p>
<pre><code class="language-shell">php artisan migrate
</code></pre>
<h2 id="configforspaauthentication">Config for SPA Authentication</h2>
<p>Sanctum uses Laravel's built-in cookie based session authentication services. You get CSRF protection, session auth, and leakage protection of auth credentials via XSS.</p>
<p><strong>Note! Because using cookies, SPA and API must share the same TLD but can be on separate subdomains.</strong></p>
<h3 id="firstpartydomains">First Party Domains</h3>
<p>Decide what domain(s) the SPA will be making requests from using <code>stateful</code> config in <code>config/sanctum.php</code> or set as <code>SANCTUM_STATEFUL_DOMAINS</code> in <code>.env[.local]</code></p>
<p>The Sanctum config file accepts a comma-separated list of domains. Include port numbers, if required!</p>
<p>&quot;Stateful&quot; means the cookies will be set for these domains. If the cookie exists, the SPA is authenticated. The session cookie being stored in the browser signifies the app knows the user is logged in and can retrieve information about the logged in user. A &quot;stateless&quot; system would require a token to be passed to the API on every single request.</p>
<h3 id="addmiddleware">Add Middleware</h3>
<p>Add <code>EnsureFrontendRequestsAreStateful::class,</code> to <code>api</code> middleware group in <code>app/Http/Kernel.php</code> file.</p>
<h3 id="corscookies">CORS &amp; Cookies</h3>
<p>Update <code>supports_credentials</code> to <code>true</code> in <code>config/cors.php</code> file. This ensures the applications CORS configuration is returning the <code>Access-Control-Allow-Credentials</code> header with a value of <code>True</code>.</p>
<p>More on CORS: <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS">https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS</a></p>
<p><strong>Gotcha:</strong> One thing to note, which tripped me up for a bit. When requesting a cookie from <code>/sanctum/csrf-cookie</code> from a <strong>domain other than the API</strong>, ensure you set <code>&quot;credentials&quot; : &quot;include&quot;</code> or the cookie won't be saved to browser storage.</p>
<p><img src="https://firebasestorage.googleapis.com/v0/b/firescript-577a2.appspot.com/o/imgs%2Fapp%2Ftoddsmithsalter%2F_xvajiTaLB.png?alt=media&amp;token=75fe8429-242a-4723-b1d3-d7d9b68bb7fc" alt="Getting Started with Laravel Sanctum"></p>
<p>Axios make this easy with the following global configuration.</p>
<pre><code class="language-javascript">axios.defaults.withCredentials = true;
</code></pre>
<p>Lastly, update sessions cookie domain config in <code>config/session.php</code> or <code>.env</code> to allow subdomains.</p>
<pre><code class="language-php">'domain' =&gt; '.domain.com',
</code></pre>
<h3 id="protectingroutes">Protecting Routes</h3>
<p>Attach the <code>sanctum</code> authentication guard to API routes in the <code>routes/api.php</code> file. All requests to these routes require the <code>X-XSRF-TOKEN</code> header or a valid API token header.</p>
<pre><code class="language-php">use Illuminate\Http\Request;

Route::middleware('auth:sanctum')-&gt;get('/user', function (Request $request) {
    return $request-&gt;user();
});
</code></pre>
<h2 id="authenticating">Authenticating</h2>
<h3 id="csrf">CSRF</h3>
<p>To authenticate the SPA, the &quot;login&quot; page should first make a request to <code>/sanctum/csrf-cookie</code> endpoint to initialize. This sets an <code>XSRF-TOKEN</code> cookie, which should be passed in an <code>X-XSRF-TOKEN</code> header on subsequent requests.</p>
<pre><code class="language-javascript">axios.get('/sanctum/csrf-cookie').then(response =&gt; {
    // Login...
});
</code></pre>
<h3 id="loggingin">Logging In</h3>
<p>Now a <code>POST</code> request to <code>/login</code> can be implemented.</p>
<p>If successful, subsequent requests to application routes will be automatically authenticated via the session cookie that the Laravel app issued to the client.</p>
<p>If the users' session expires due to lack of activity and a 401 or 419 HTTP response is received, redirect to <code>/login</code>.</p>
<h2 id="nextup">Next Up</h2>
<p>This is only step one. Now to configure user token authentication with <a href="https://laravel.com/docs/8.x/fortify">Laravel Fortify</a> a <a href="https://laravel.com/docs/8.x/authentication#authenticating-users">custom implementation</a>.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Restarting my development engine]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>For the past several years, I've bounced necessarily between sectors such as consulting, media production, construction, and oil &amp; gas. While I'd like to say this has been by choice, each position change has been a result of forces out of my control. While I won't get into the specifics</p>]]></description><link>https://toddsmithsalter.com/restarting-my-development-engine/</link><guid isPermaLink="false">5fdbf1da38b74c11bcaa2e22</guid><category><![CDATA[development]]></category><category><![CDATA[focus]]></category><category><![CDATA[overwhelm]]></category><dc:creator><![CDATA[Todd Smith-Salter]]></dc:creator><pubDate>Fri, 18 Dec 2020 00:16:55 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1552962730-61f41ae62092?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MXwxMTc3M3wwfDF8c2VhcmNofDIyfHxtY2xhcmVuJTIwcmFjZSUyMGNhcnxlbnwwfHx8&amp;ixlib=rb-1.2.1&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://images.unsplash.com/photo-1552962730-61f41ae62092?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=MXwxMTc3M3wwfDF8c2VhcmNofDIyfHxtY2xhcmVuJTIwcmFjZSUyMGNhcnxlbnwwfHx8&ixlib=rb-1.2.1&q=80&w=2000" alt="Restarting my development engine"><p>For the past several years, I've bounced necessarily between sectors such as consulting, media production, construction, and oil &amp; gas. While I'd like to say this has been by choice, each position change has been a result of forces out of my control. While I won't get into the specifics here, it's been a welcome change to get back into web development.</p>
<p>So, here I find myself wanting to and actively getting back into building websites. I've had experience with a number of popular frameworks and CMS's but I've been excited to have the opportunity to flex my thinker (that's my brain 🤔) and learn something completely new to me.</p>
<p>I have to say, developers are not bereft for choice when deciding what to use. I mean, there are so many options it's paralyzing.</p>
<p>Some of the questions I've asked myself are...</p>
<ul>
<li>Should I learn a new-to-me language, like <a href="https://www.python.org/">Python</a> or <a href="https://www.ruby-lang.org/en/">Ruby</a>?</li>
<li>Should I stick good old hardy <a href="https://www.php.net/">php</a>?</li>
<li>Is <a href="https://laravel.com/">Laravel</a> still The Best™ framework for php development?</li>
<li>Should I try to build in <a href="https://rubyonrails.org/">Rails</a>? <a href="https://twitter.com/dhh">@DHH</a>, so it should be awesome, right?</li>
<li>I've used <a href="https://emberjs.com/">EmberJS</a> a heap-load. Should I use <a href="https://reactjs.org/">React</a> or <a href="https://vuejs.org/">Vue</a> instead?</li>
<li>What about <a href="https://angular.io/">Angular</a>...is it still a thing?</li>
<li>And what about a build tool? <a href="https://webpack.js.org/">webpack</a>, <a href="https://parceljs.org/">parcel</a>, <a href="https://gulpjs.com/">Gulp</a>, <a href="https://gruntjs.com/">Grunt</a>, <a href="https://broccoli.build/">broccoli</a>, etc.</li>
<li>What front-end framework should I learn/use/become an expert in? <a href="https://reactjs.org/docs/create-a-new-react-app.html">create-react-app</a>, <a href="https://nextjs.org/">NextJS</a>, <a href="https://nuxtjs.org/">NuxtJS</a>, <a href="https://www.gatsbyjs.com/">Gatsby</a>, etc.</li>
<li>Should I split App from API?</li>
<li>Should I build a monolith app?</li>
<li><a href="https://en.wikipedia.org/wiki/Representational_state_transfer">REST</a> or <a href="https://graphql.org/">GraphQL</a> API? Wait, <strong>what's GraphQL???</strong></li>
</ul>
<p>This could go on for awhile.</p>
<p>My point is, there are so many options, so many decisions to make, it can so easily bring me to a grinding halt.</p>
<h2 id="abstractions">Abstractions</h2>
<p>Has web development always been like this? I really don't think so. As humans learn and systems evolve, we build abstraction layers above what we consider trivial tasks.</p>
<p>In web development, we've abstracted HTML, CSS, and Javascript behind layers and layers of build tools, modules, references, props, composers, INSERT_FANCY_NAME_HERE.</p>
<p>I'm not saying abstractions are a bad thing. In fact, I think they're the opposite. These abstractions breed technological advancements we wouldn't have dreamed about years ago. It's simply the case that we are option-wealthy. Not only are there thousands of packages already created we can learn from and use as developers, hundreds more are added everyday. We are in a development golden age.</p>
<p>For those us of who have been on pause or stepped away from development for a time, stepping back into this raging torrent is overwhelming. Seriously mind-numbing. I feel like Neo looking at the Matrix for the first time, overwhelmed by the flood of data. I can't mentally parse the signal from the noise.</p>
<h2 id="summary">Summary</h2>
<p>My first couple weeks back in the saddle have brought me to surmise the following:</p>
<ul>
<li>Make a quick and educated choice to learn one language/framework/concept and see it to completion.</li>
<li>Block new wizz-bang fanciness, the distractions competing for attention as I learn language/framework/concept above.</li>
<li>Build something real. I'm rebuilding gpjobs.ca as a NextJS + Laravel API app.</li>
</ul>
<p>I hope after a few weeks of hard focused work, I have a good return and can be proud of my work. I think that's the best I can ask for.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Sunsetting gpjobs.ca]]></title><description><![CDATA[<p>I created gpjobs.ca as a passion project for a couple reasons. </p><ol><li>Create a space where Grande Prairie businesses could connect with great prospects.</li><li>To learn new programming tools, specifically <a href="https://laravel.com/">Laravel</a>.</li><li>To earn some residual income.</li></ol><p>While I learned quite a bit about the first two through brute force and</p>]]></description><link>https://toddsmithsalter.com/sunsetting-gpjobs-ca/</link><guid isPermaLink="false">5fdbd54b38b74c11bcaa2ddc</guid><dc:creator><![CDATA[Todd Smith-Salter]]></dc:creator><pubDate>Mon, 16 Nov 2020 18:34:44 GMT</pubDate><media:content url="https://toddsmithsalter.com/content/images/2020/11/Screen-Shot-2020-11-16-at-11.23.21-AM.png" medium="image"/><content:encoded><![CDATA[<img src="https://toddsmithsalter.com/content/images/2020/11/Screen-Shot-2020-11-16-at-11.23.21-AM.png" alt="Sunsetting gpjobs.ca"><p>I created gpjobs.ca as a passion project for a couple reasons. </p><ol><li>Create a space where Grande Prairie businesses could connect with great prospects.</li><li>To learn new programming tools, specifically <a href="https://laravel.com/">Laravel</a>.</li><li>To earn some residual income.</li></ol><p>While I learned quite a bit about the first two through brute force and involvement in a local job fair as title sponsor, gpjobs.ca was ultimately a fiscal failure and an experience success.</p><p>I've moved on to other projects and it's time to shut the doors. Perhaps not forever. gpjobs.ca may return in some metamorphosed form in the future.</p><p>Sayonara gpjobs.ca. It was fun. </p>]]></content:encoded></item><item><title><![CDATA[Focus]]></title><description><![CDATA[<p>When I feel overwhelmed, I'm Peter looking out over the Sea of Galilee noticing the scary storm waves rather than Jesus walking on the water. When Peter lost focus on Christ, he sunk in the waves. When I focus on a singular area letting the fear and unknown slip away</p>]]></description><link>https://toddsmithsalter.com/focus/</link><guid isPermaLink="false">5fdbd54b38b74c11bcaa2dda</guid><category><![CDATA[focus]]></category><category><![CDATA[fear]]></category><category><![CDATA[overwhelm]]></category><dc:creator><![CDATA[Todd Smith-Salter]]></dc:creator><pubDate>Thu, 29 Oct 2020 21:21:16 GMT</pubDate><content:encoded><![CDATA[<p>When I feel overwhelmed, I'm Peter looking out over the Sea of Galilee noticing the scary storm waves rather than Jesus walking on the water. When Peter lost focus on Christ, he sunk in the waves. When I focus on a singular area letting the fear and unknown slip away from conscious thought, I'm able to do so much more.</p>]]></content:encoded></item><item><title><![CDATA[Rejection is Hard]]></title><description><![CDATA[<p>For the first time ever, I did not get a job I interviewed for. This was my first technical interview and I knew there was a very good chance I wouldn’t get the job, yet it still doesn’t feel good.</p><p>It feels like what I bring to the</p>]]></description><link>https://toddsmithsalter.com/rejection-is-hard/</link><guid isPermaLink="false">5fdbd54b38b74c11bcaa2dd8</guid><category><![CDATA[personal]]></category><dc:creator><![CDATA[Todd Smith-Salter]]></dc:creator><pubDate>Tue, 11 Jun 2019 15:56:34 GMT</pubDate><content:encoded><![CDATA[<p>For the first time ever, I did not get a job I interviewed for. This was my first technical interview and I knew there was a very good chance I wouldn’t get the job, yet it still doesn’t feel good.</p><p>It feels like what I bring to the table isn’t valued. Perhaps it isn’t. Perhaps I wasn’t ready for approval.</p><p>Regardless of the other party’s reasons, it’s up to me to decide how to respond to the rejection.</p><p>Will I wallow in the sting, feel hopeless, and give up?</p><p>Can I take the rejection as a motivator, learn from my mistakes, and move on to another opportunity?</p><p>The ball is in my court, so to speak.</p>]]></content:encoded></item><item><title><![CDATA[Prioritizing Sleep]]></title><description><![CDATA[I have found the most important activity I can do to improve my overall state of mind and health is to get enough sleep. ]]></description><link>https://toddsmithsalter.com/prioritizing-sleep/</link><guid isPermaLink="false">5fdbd54b38b74c11bcaa2dd6</guid><dc:creator><![CDATA[Todd Smith-Salter]]></dc:creator><pubDate>Mon, 14 May 2018 12:28:51 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>I have found the most important activity I can do to improve my overall state of mind and health is to get enough sleep.</p>
<p>Once upon a time, I would go to bed late and get up early every night, getting 6 hours of sleep or less. As I’ve grown older and developed habits and routines, I discovered though observation and reflection I need at least seven hours of sleep each night.</p>
<p>When I get seven hours of sleep I feel rested and able to logically think through my day’s priority and the tasks ahead. I can prioritize and make wise choices.</p>
<p>When I get less than seven hours my mind is foggy and fractured. Decisions seem less clear. I am easily distracted. I haven’t built up willpower reserves to begin to make wise choices.</p>
<p>I decided at the beginning of the year to always get seven hours of sleep, even if it means changing my wake-up time because a I stayed up late.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Success isn't an accident]]></title><description><![CDATA[Success, or what you define as success, financial or otherwise, are a direct result of behaviours. The small tasks, the habits you do every day create an environment of motion and progress.]]></description><link>https://toddsmithsalter.com/success-isnt-an-accident/</link><guid isPermaLink="false">5fdbd54b38b74c11bcaa2dd5</guid><category><![CDATA[productivity]]></category><dc:creator><![CDATA[Todd Smith-Salter]]></dc:creator><pubDate>Thu, 03 May 2018 16:45:35 GMT</pubDate><media:content url="https://toddsmithsalter.com/content/images/2018/05/estee-janssens-396887-unsplash.jpg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://toddsmithsalter.com/content/images/2018/05/estee-janssens-396887-unsplash.jpg" alt="Success isn't an accident"><p>Success, or what you define as success, financial or otherwise, are a direct result of behaviours. The small tasks, the habits you do every day create an environment of motion and progress.</p>
<p>Do you want financial success? Spend less than you make <em>every day</em>.</p>
<p>Do you want to be mentally free to focus on family on the weekends? Use your time and task management system religiously. Don't stray.</p>
<p>Do you want to learn how to code so you can open up an online shop? Practice every day. Just 30 minutes a day adds up to almost 3.5 hours a week.</p>
<p>The only barrier to success is ourselves. &quot;I don't have time&quot; or &quot;I'm so busy&quot; end up just being excuses.</p>
<blockquote>
<p>“You will never change your life until you change something you do daily. The secret of your success is found in your daily routine.”<br>
– <em>John C. Maxwell</em></p>
</blockquote>
<p>I'm say this as much to myself as anyone: <em>just do it</em>. Success won't come by accident.</p>
<hr>
<p>Photo by <a href="https://unsplash.com/photos/zEqkUMiMxMI?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Estée Janssens</a> on <a href="https://unsplash.com/search/photos/journal?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Why I deleted Facebook]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>Derek Silvers on his <a href="https://sivers.org/facebook">blog</a>:</p>
<blockquote>
<p>Maybe the fact that I use it to share my blog posts is a tiny tiny reason why others are still using it. It’s like I’m still visiting friends in the smoking area, even though I don’t smoke. Maybe if I quit</p></blockquote>]]></description><link>https://toddsmithsalter.com/why-i-deleted-facebook/</link><guid isPermaLink="false">5fdbd54b38b74c11bcaa2dd4</guid><dc:creator><![CDATA[Todd Smith-Salter]]></dc:creator><pubDate>Wed, 21 Mar 2018 12:24:57 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>Derek Silvers on his <a href="https://sivers.org/facebook">blog</a>:</p>
<blockquote>
<p>Maybe the fact that I use it to share my blog posts is a tiny tiny reason why others are still using it. It’s like I’m still visiting friends in the smoking area, even though I don’t smoke. Maybe if I quit going entirely, it will help my friends quit, too.</p>
</blockquote>
<p>I understand this quandry. Facebook has become a lose-lose scenario for me. If I spend time there it distracts me from what's really important, the people around me and the deep work I want to accomplish. My reasons for keeping my Facebook account are selfish and out of fear. &quot;I need it for work.&quot; &quot;I'll lose touch with INSERT NAME.&quot; &quot;I'll keep it around but won't use it.&quot; Excuses. That's all they are.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[My Morning Routine]]></title><description><![CDATA[Limited willpower is the most significant obstacle to getting things done. I only have so much available to make decisions. Every decision I have to make means it’s less likely I’ll take action.]]></description><link>https://toddsmithsalter.com/my-wake-up-routine/</link><guid isPermaLink="false">5fdbd54b38b74c11bcaa2dd3</guid><category><![CDATA[productivity]]></category><dc:creator><![CDATA[Todd Smith-Salter]]></dc:creator><pubDate>Tue, 20 Mar 2018 12:37:00 GMT</pubDate><media:content url="https://toddsmithsalter.com/content/images/2018/03/20180320-P3200006.jpg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://toddsmithsalter.com/content/images/2018/03/20180320-P3200006.jpg" alt="My Morning Routine"><p>Limited willpower is the most significant obstacle to getting things done. I only have so much available to make decisions. Every decision I have to make means it’s less likely I’ll take action. In his book <em>Deep Work</em>, Cal Newport states, “You have a finite amount of willpower that becomes depleted as you use it.”</p>
<p>A couple routines and rituals I’ve instituted in my life to ensure I reserve my willpower for actionable tasks are to have a wake-up routine and to choose my clothes I’ll wear for the day the night before. Choosing my clothes prevents me from having to use my fresh-from-sleep mind from an insignificant decision. My wake-up routine means I don’t have to think about what I’m going to do when I get up, I just do it.</p>
<p>For full transparency, my morning routine is to get up around 4:30 am, get dressed in the clothes I’ve set out, use the washroom, make Earl Grey tea, write, read my Bible and journal, do some work until 7 am, make breakfast, get my kids ready for the day, and finally, walk to my office.</p>
<p>I thrive on routine. Keeping this routine has saved my energy and willpower for what’s most important, the essentials.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Screw The Golden Rule]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p><a href="https://twitter.com/cjlew23">Claire Lew</a> at <a href="https://www.inc.com/claire-lew/screw-golden-rule-managers-do-not-treat-employees-way-youd-like-to-be-treated-heres-why.html">Inc.</a>:</p>
<blockquote>
<p>The other person has different preferences (beliefs, ideas, and experiences) and is going to react to a situation differently than you. You might think something is reasonable or fair, but that's you thinking that, not the other person. You cannot assume that the way she would</p></blockquote>]]></description><link>https://toddsmithsalter.com/screw-the-golden-rule/</link><guid isPermaLink="false">5fdbd54b38b74c11bcaa2dd2</guid><category><![CDATA[leadership]]></category><dc:creator><![CDATA[Todd Smith-Salter]]></dc:creator><pubDate>Thu, 26 Oct 2017 17:58:53 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p><a href="https://twitter.com/cjlew23">Claire Lew</a> at <a href="https://www.inc.com/claire-lew/screw-golden-rule-managers-do-not-treat-employees-way-youd-like-to-be-treated-heres-why.html">Inc.</a>:</p>
<blockquote>
<p>The other person has different preferences (beliefs, ideas, and experiences) and is going to react to a situation differently than you. You might think something is reasonable or fair, but that's you thinking that, not the other person. You cannot assume that the way she would like to be treated is the same as the way you'd like to be treated.</p>
</blockquote>
<p>I find it's a constant struggle to put myself in my Team Member's shoes and not treat them <em>exactly how I want to be treated</em>. That's the golden ticket in this article. I want to be treated one way. Someone else wants to be treated another way. Context is king.</p>
<p>There's a great list of questions Claire lists at the bottom of the article worth jotting down for one-on-ones.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item></channel></rss>