Kissaki

joined 1 year ago
[–] Kissaki 2 points 1 week ago* (last edited 1 week ago)

Code before:

async function createUser(user) {
    if (!validateUserInput(user)) {
        throw new Error('u105');
    }

    const rules = [/[a-z]{1,}/, /[A-Z]{1,}/, /[0-9]{1,}/, /\W{1,}/];
    if (user.password.length >= 8 && rules.every((rule) => rule.test(user.password))) {
        if (await userService.getUserByEmail(user.email)) {
            throw new Error('u212');
        }
    } else {
        throw new Error('u201');
    }

    user.password = await hashPassword(user.password);
    return userService.create(user);
}

Here's how I would refac it for my personal readability. I would certainly introduce class types for some concern structuring and not dangling functions, but that'd be the next step and I'm also not too familiar with TypeScript differences to JavaScript.

const passwordRules = [/[a-z]{1,}/, /[A-Z]{1,}/, /[0-9]{1,}/, /\W{1,}/]
function validatePassword(plainPassword) => plainPassword.length >= 8 && passwordRules.every((rule) => rule.test(plainPassword))
async function userExists(email) => await userService.getUserByEmail(user.email)

async function createUser(user) {
    // What is validateUserInput? Why does it not validate the password?
    if (!validateUserInput(user)) throw new Error('u105')
    // Why do we check for password before email? I would expect the other way around.
    if (!validatePassword(user.password)) throw new Error('u201')
    if (!userExists(user.email)) throw new Error('u212')

    const hashedPassword = await hashPassword(user.password)
    return userService.create({ email: user.email, hashedPassword: hashedPassword });
}

Noteworthy:

  • Contrary to most JS code, [for independent/new code] I use the non-semicolon-ending style following JavaScript Standard Style - see their no semicolons rule with reasoning; I don't actually know whether that's even valid TypeScript, I just fell back into JS
  • I use oneliners for simple check-error-early-returns
  • I commented what was confusing to me
  • I do things like this to fully understand code even if in the end I revert it and whether I implement a fix or not. Committing refacs is also a big part of what I do, but it's not always feasible.
  • I made the different interface to userService.create (a different kind of user object) explicit
  • I named the parameter in validatePassword plainPasswort to make the expectation clear, and in the createUser function more clearly and obviously differentiate between "the passwords"/what password is. (In C# I would use a param label on call validatePassword(plainPassword: user.password) which would make the interface expectation and label transformation from interface to logic clear.

Structurally, it's not that different from the post suggestion. But it doesn't truth-able value interpretation, and it goes a bit further.

[–] Kissaki 2 points 1 week ago (2 children)

2FA? But it said "with one click". So that's not true?

[–] Kissaki 2 points 1 week ago

I don't remember whether I serious considered that. I don't see it in the Play store. I likely preferred original source.

Looking at the screenshots, it looks like a waste of space. A no go for me, given the alternative.

https://keepassxc.org/assets/img/screenshots/database_view.png

Compare that to the condensed, concise Keepass interface:

https://keepass.info/screenshots/keepass_2x/main_big.png

[–] Kissaki 1 points 1 week ago

Being able to build the app as you are trying to do here is an issue we plan to resolve and is merely a bug.

[–] Kissaki 12 points 1 week ago

Being able to build the app as you are trying to do here is an issue we plan to resolve and is merely a bug.

[–] Kissaki 3 points 1 week ago* (last edited 1 week ago) (2 children)

I use KeePass and manually sync my password database file through cloud storage. I specifically prefer it over anything giving me web and online interfaces. I load from local file or on my phone from cloud storage.

[–] Kissaki 14 points 1 week ago (2 children)

So it really is that simple: a small bash script, building locally, rsync'ing the changes, and restarting the service. It's just the bare essentials of a deployment. That's how I deploy in 10 seconds.

I'm strongly opposed to local builds on any semi-important or semi-complex production product or system.

Tagged CI release builds give you a lot of important guarantees involved in release concerns.

I'll take the fresh checkout and release build time cost for those consistency and versioned source state guarantees.

[–] Kissaki 10 points 1 week ago

learned from 10 years/millions of users in production

10 years per millions of users is an interesting metric :P

[–] Kissaki 1 points 2 weeks ago* (last edited 2 weeks ago)

I wasn't aware the GitHub terms of service explicitly grant / require you to grant permission to fork [within GitHub].

GitHub ToS section License Grant to Other Users

By setting your repositories to be viewed publicly, you agree to allow others to view and "fork" your repositories (this means that others may make their own copies of Content from your repositories in repositories they control).

If you set your pages and repositories to be viewed publicly, you grant each User of GitHub a nonexclusive, worldwide license to use, display, and perform Your Content through the GitHub Service and to reproduce Your Content solely on GitHub as permitted through GitHub's functionality (for example, through forking). […] If you are uploading Content you did not create or own, you are responsible for ensuring that the Content you upload is licensed under terms that grant these permissions to other GitHub Users.

[–] Kissaki 16 points 2 weeks ago* (last edited 2 weeks ago)

It's been over 10 years since we released Rogue Legacy 1, and in the pursuit of sharing knowledge, we are officially releasing the source code to the public.

https://github.com/flibitijibibo/RogueLegacy1/

License head

Rogue Legacy 1's source code is made available under a custom license. Basically, you can compile yourself a copy, for free, for personal use. But if you want to distribute a compiled version of the game, you might need permission first. See the EXCEPTIONS.md page for more information.

[–] Kissaki 1 points 2 weeks ago

Yeah, I thought the same. Pretty bad name.

 

When you pause while debugging, you can hover over any delegate and get a convenient go to source link, here is an example with a Func delegate.

If you already know about delegates, there's not a lot of content in this dev blog post. Not that that's necessarily a bad thing either.

 

Mapping C# array types to PostgreSQL array columns or other DBMS/DB JSON columns.

 

Available and enabled by default from version 17.11 Preview 2 onwards.

New resource explorer additionally supports search, single view across solution, edit multiple files and locales at once, dark mode, string.Format pattern validation, validation and warnings, combined string and media view, grid zoomability

 

cross-posted from: https://programming.dev/post/11720354

UI Components: Smart Paste, Smart TextArea, Smart ComboBox

Dependency: Azure Cloud

They show an interesting new kind of interactivity. (Not that I, personally, would ever use Azure Cloud for that though.)

 

UI Components: Smart Paste, Smart TextArea, Smart ComboBox

Dependency: Azure Cloud

They show an interesting new kind of interactivity. (Not that I, personally, would ever use Azure Cloud for that though.)

 

Backwards compatibility is a key principle in .NET, and this means that packages targeting previous .NET versions, like ‘net6.0’ or ‘net7.0’, are also compatible with ‘net8.0’. […]

The new “Include compatible frameworks” option we added allows you to flip between filtering by explicit asset frameworks and the larger set of ‘compatible’ frameworks. Filtering by packages’ compatible frameworks now reveals a much larger set of packages for you to choose from.

 

Truly astonishing how much generalized modding seems to be possible through general DirectX (8/9) interfaces and official Nvidia provided tooling.

As an AMD graphics card user, it's very unfortunate that RTX/this functionality is proprietary/exclusive Nvidia. The tooling at least. The produced results supposedly should work on other graphics cards too (I didn't find official/upstream docs about it).

For more technical details of how it works, see the GameWorks wiki:

 

cross-posted from: https://programming.dev/post/11034601

There's a lot, and specifically a lot of machine learning talk and features in the 1.5 release of Opus - the free and open audio codec.

Audible and continuous (albeit jittery) talk on 90% packet loss is crazy.

Section WebRTC IntegrationSamples has an example where you can test out the 90 % packet loss audio.

 

There's a lot, and specifically a lot of machine learning talk and features in the 1.5 release of Opus - the free and open audio codec.

Audible and continuous (albeit jittery) talk on 90% packet loss is crazy.

Section WebRTC IntegrationSamples has an example where you can test out the 90 % packet loss audio.

view more: ‹ prev next ›