ChanServ changed the topic of #crystal-lang to: The Crystal programming language | http://crystal-lang.org | Crystal 0.32.0 | Fund Crystal's development: http://is.gd/X7PRtI | GH: https://github.com/crystal-lang/crystal | Docs: http://crystal-lang.org/docs/ | API: http://crystal-lang.org/api/ | Gitter: https://gitter.im/crystal-lang/crystal
<FromGitter> <randiaz95> Hey Blacksmoke
<FromGitter> <randiaz95> How you feel man
<FromGitter> <Blacksmoke16> o/
<FromGitter> <randiaz95> or woman
<FromGitter> <Blacksmoke16> its going
<FromGitter> <randiaz95> dude, I recommend playing this while you code:
<FromGitter> <randiaz95> piano
<FromGitter> <Blacksmoke16> haha ill have to check it out
<FromGitter> <randiaz95> ima focus on finishing my little app I have been working on
<FromGitter> <Blacksmoke16> 👍 sounds like a plan
<FromGitter> <randiaz95> but I will probably log in tomorrow night or monday night
<FromGitter> <Blacksmoke16> currently im trying to figure out why im getting a segfault
<FromGitter> <randiaz95> Are you using a pointer?
<FromGitter> <Blacksmoke16> naw
<FromGitter> <randiaz95> I think segfault has to do with illegally accessing a memory location
<FromGitter> <Blacksmoke16> indeed
<FromGitter> <Blacksmoke16> the question is why im getting one :p
<FromGitter> <Blacksmoke16> seems the request obj is becoming corrupt
<FromGitter> <randiaz95> lol.
<FromGitter> <randiaz95> maybe its getting corrupt over the wifi radiation to your computer
<FromGitter> <randiaz95> are you hosting it in localhost or wifi ip?
<FromGitter> <Blacksmoke16> looks like one of my objects is being mutated somehow
<FromGitter> <randiaz95> wierd,
<FromGitter> <randiaz95> can you make the object a constant?
<FromGitter> <Blacksmoke16> granted a lot of stuff is going on that could be doing it
<FromGitter> <Blacksmoke16> i got a DI service container within the framework, so possible something is going wrong there
<FromGitter> <randiaz95> :/ that went over my head lol
<FromGitter> <randiaz95> Blacksmoke, do you have working knowledge of Ruby Threads?
<FromGitter> <Blacksmoke16> not really, havent used ruby that much
<FromGitter> <randiaz95> Oh ok. I was wondering because crystal has similar syntax
<FromGitter> <Blacksmoke16> thats about all they share
<FromGitter> <Blacksmoke16> some design decisions differ as well but they arent the same lang
<FromGitter> <randiaz95> I agree, ruby feels more functional
<FromGitter> <pynixwang> `private def stdio_to_fd(stdio : Stdio, for dst_io : IO::FileDescriptor) : IO::FileDescriptor`
<FromGitter> <pynixwang> what does `for` mean?
<FromGitter> <pynixwang> like swift
<FromGitter> <randiaz95> That looks like a mistake, does that actually compile?
<FromGitter> <pynixwang> outer name
<FromGitter> <randiaz95> or maybe some alias
<FromGitter> <Blacksmoke16> External and internal names
<FromGitter> <pynixwang> gets
<FromGitter> <pynixwang> An external name can be specified for a method argument. The external name is the one used when passing an argument as a named argument, and the internal name is the one used inside the method definition:
<FromGitter> <pynixwang> in crystal book
<FromGitter> <randiaz95> guys, is it bad practice to make a hash of hashes? or should I make a hash of objects?
<FromGitter> <pynixwang> swift has this feature.
<FromGitter> <randiaz95> For example distances = {"NY" => {"NY": 0, "MIAMI":123, "CALIFORNIA": 532 }, "MIAMI: {}...}
<FromGitter> <randiaz95> then go distances["NY"]["MIAMI"]
<FromGitter> <Blacksmoke16> Hash of objects would be better
_whitelogger has joined #crystal-lang
<FromGitter> <Blacksmoke16> named tuple would be best if the data is static
return0e has quit [Ping timeout: 240 seconds]
return0e has joined #crystal-lang
duane has quit [Quit: Lost terminal]
<FromGitter> <randiaz95> I really appreciate that crystal doesnt need crystal `run` but just crystal filename.cr
return0e_ has joined #crystal-lang
return0e has quit [Ping timeout: 240 seconds]
return0e_ has quit [Read error: Connection reset by peer]
return0e has joined #crystal-lang
_whitelogger has joined #crystal-lang
return0e has quit [Read error: Connection reset by peer]
return0e has joined #crystal-lang
_whitelogger has joined #crystal-lang
_whitelogger has joined #crystal-lang
ht_ has joined #crystal-lang
<oprypin_> randiaz95, how about `{ {"NY", "MIAMI"} => 123, {"NY", "CALIFORNIA"} => 532}`
<FromGitter> <lbarasti> Is it possible to load classes at boot time - say from config values? @Blacksmoke16 does you DI implementation turn class names into instances somehow?
echosystm has joined #crystal-lang
echosystm has quit [Quit: leaving]
foxxx0 has joined #crystal-lang
DTZUZO has quit [Ping timeout: 250 seconds]
<Yxhuvud> lbarasti: no.
<FromGitter> <lbarasti> Thanks @yxhuvud, is there some sort of workaround people have been playing with - that you know?
<Yxhuvud> Create classes during boot if you want, but you need to know what you will be creating.
<Yxhuvud> *class instances. Not classes.
<FromGitter> <lbarasti> yes, I see what you mean. Maybe some class registration mechanism? Sounds awfully complicated
<Yxhuvud> I'd refactor so that I don't need to create new classes.
<FromGitter> <dscottboggs_gitlab> Hey @Blacksmoke16, I've noticed you've been making contributions to the compiler, that's pretty cool. I was wondering if you (or other compiler contributors) have any resources for getting started working with the compiler? A high-level overview of how the components fit together perhaps?
<FromGitter> <dscottboggs_gitlab> i've read a decent chunk of it but I still can't quite figure out how it all fits together
<FromGitter> <randiaz95> @FromIRC how would I access the data from a data structure like that?
<FromGitter> <dscottboggs_gitlab> are you talking about Oprypin's `Hash(Set, Int32)`?
<FromGitter> <dscottboggs_gitlab> https://carc.in/#/r/879f
<FromGitter> <randiaz95> yes
<FromGitter> <randiaz95> and I mean, doesn't it take non-constant time to unhash a set?
<FromGitter> <dscottboggs_gitlab> unhash?
<FromGitter> <randiaz95> interesting.
<FromGitter> <randiaz95> I mean, the benefits of using a hash map is that it is fast to lookup the items, will the hashmap perform the same with a set as a key?
<FromGitter> <tenebrousedge> hash and set are both O(1) access. Set is implemented using `Hash`
<FromGitter> <tenebrousedge> and generally elements/keys are compared by `hash` value
<FromGitter> <tenebrousedge> i.e. `"123".hash`
<FromGitter> <dscottboggs_gitlab> I don't think performance will have a significant enough impact to be concerned about when it comes to this, TBH. Just stick it in a structure that makes sense. But there's always the `Benchmark` module
<FromGitter> <tenebrousedge> so one set should hash to the same value as a set with the same elements
<FromGitter> <tenebrousedge> also, ignore performance until you have customer complaints
<FromGitter> <dscottboggs_gitlab> this
<FromGitter> <dscottboggs_gitlab> crystal is fast
<FromGitter> <dscottboggs_gitlab> let the compiler be fast and write code that makes sense
<FromGitter> <randiaz95> Right, I agree... I am refactoring my ruby mvp app to crystal
<FromGitter> <randiaz95> it should be way faster anyways.
<FromGitter> <randiaz95> Thank you very much!
<FromGitter> <tenebrousedge> np
<FromGitter> <randiaz95> Crystal is super cool
<FromGitter> <dscottboggs_gitlab> OTOH, a `Hash(String, Hash(String, Int32))` has two lookups to get to the value, and `Hash(Set(String), Int32)` or `Hash(CityPairStruct, Int32)` would only have one.
<FromGitter> <randiaz95> That sounds logical, Sry I am used to python not allowing anything but strings
<FromGitter> <randiaz95> for keys in a dictionary
<FromGitter> <dscottboggs_gitlab> Yes, in Crystal, any type which defines a `hash` method can be used as a key in a Hash. For most types you can just add the line `def_equals_and_hash` to the type and it will just work.
<FromGitter> <randiaz95> Kind of like a go-lang interface. That is super powerful.
<FromGitter> <dscottboggs_gitlab> yes crystal also has interfaces :) weirdly called modules though. Must be a ruby thing haha
<FromGitter> <tenebrousedge> yes, modules are from Ruby. I don't know how much they relate to golang <__< dun like golang
<FromGitter> <dscottboggs_gitlab> I don't like it either but that's because I've used it before haha
<FromGitter> <randiaz95> I think now, the thing slowing me down is the client side code... Javascript is a mess man.
<FromGitter> <tenebrousedge> no lie
HumanG33k has quit [Ping timeout: 240 seconds]
<FromGitter> <dscottboggs_gitlab> ooof goddamn I've had some frustrating JS bugs lately
<FromGitter> <randiaz95> Do you guys dominate promise/await? I need some resource to learn that...
<FromGitter> <dscottboggs_gitlab> like a value being set somehow to the string `"undefined"`... fuckin `[1, 2, 3] + [4, 5, 6]` returning the string `"[1,2,3][4,5,6]"` ugh
<FromGitter> <tenebrousedge> the best JS resource is You Don't Know JS
<FromGitter> <dscottboggs_gitlab> idk I mean I use `async/await` when I have to. Promises with chained `then` calls were fine too to me
<FromGitter> <tenebrousedge> https://github.com/getify/You-Dont-Know-JS
<FromGitter> <tenebrousedge> it's a free ebook series that is unparalleled in depth and clarity
<FromGitter> <randiaz95> Thanks Kai! Are you related to King Kai or Supreme Kai?
<FromGitter> <tenebrousedge> those guys won't even return my phone calls :(
<FromGitter> <Blacksmoke16> @lbarasti the container gets built out at compile time, which means all registered services get instantiated and set on the container
<FromGitter> <Blacksmoke16> services that have dependencies of their own you specify those in the annotation like ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5df6445d0616d6515e42f105]
<FromGitter> <Blacksmoke16> where `@some_service` represents ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5df64478ce2b2e652bddff87]
<FromGitter> <Blacksmoke16> non services can also inject service dependecies by doing ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5df6449c55d939230015c787]
<FromGitter> <Blacksmoke16> i based it a bit off how Symfony works, which defines their stuff in yaml ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5df64541c6ce6027ebc6b590]
<FromGitter> <Blacksmoke16> but not sure how that would work, would have to be at runtime as you can only get the string contents in a macro
<FromGitter> <Blacksmoke16> @dscottboggs_gitlab most of my changes have been for the macro side of things, which is a bit simpler
<FromGitter> <Blacksmoke16> in that case the main files you may need are the ones used https://github.com/crystal-lang/crystal/pull/8049/files
<FromGitter> <dscottboggs_gitlab> damn
<FromGitter> <dscottboggs_gitlab> this idea keeps nagging me, basically involving generating crystal code from json
HumanG33k has joined #crystal-lang
HumanG33k has quit [Remote host closed the connection]
HumanG33k has joined #crystal-lang
<FromGitter> <randiaz95> Guys, how do I filter or reduce an array in crystal? I know how to map a function to an array with .each but I haven't been able to find the keywords for filter/reduce
<FromGitter> <tenebrousedge> keywords?
<FromGitter> <Blacksmoke16> https://crystal-lang.org/api/0.31.1/Enumerable.html#select(&block:T-%3E)-instance-method
<FromGitter> <Blacksmoke16> they're under enumerable
<FromGitter> <tenebrousedge> `select` and `reduce` are methods
<FromGitter> <Blacksmoke16> https://crystal-lang.org/api/0.31.1/Enumerable.html#reduce(&block)-instance-method
<FromGitter> <tenebrousedge> devdocs.io is also a thing
<FromGitter> <randiaz95> Nice!
ht__ has joined #crystal-lang
ht_ has quit [Ping timeout: 252 seconds]
ht__ is now known as ht_
DTZUZO has joined #crystal-lang
JuanMiguel has joined #crystal-lang
<FromGitter> <randiaz95> whats up with this method syntax `def name=(name)` for a setter its pretty wild, given that obj.name = "tom" still works with spaces in between
<FromGitter> <tenebrousedge> it comes from Ruby, but what's wild about it?
<FromGitter> <tenebrousedge> if you really want you can write `obj.name=("value")`
<FromGitter> <randiaz95> I come from python, so its a little difficult to handle = and ? and ! at the end of methods.
<FromGitter> <tenebrousedge> `?` is just a convention. `=` with spaces is a little syntactic sugar. You could write `def name(name)` for a setter, but that would result in `obj.name("name")`, which isn't what I would prefer, personally
<FromGitter> <tenebrousedge> but I would just use the `setter` or `property` macros, generally
<FromGitter> <lbarasti> thanks @Blacksmoke16, it will serve me as inspiration
<FromGitter> <Blacksmoke16> np
<FromGitter> <Blacksmoke16> https://play.crystal-lang.org/#/r/87ag
<FromGitter> <Blacksmoke16> i reduced that segfault i was getting
<FromGitter> <Blacksmoke16> https://play.crystal-lang.org/#/r/87ai a bit more
<FromGitter> <Blacksmoke16> seems to be related to the controller being a struct
<FromGitter> <Blacksmoke16> prob gets allocated on the stack, then something gets borked after turning the method into the proc since im mutating an ivar in a struct that might have got de referenced?
<FromGitter> <Blacksmoke16> but it also only happens if the `Route` obj is returned from a method
<FromGitter> <randiaz95> i wonder how people learn faster... I feel like it took me 1 year to learn basic java with objects and now it takes me 1 week to learn crystal
<FromGitter> <randiaz95> @Blacksmoke16 do you think your segfault is happening because of the garbage collector?
<FromGitter> <tenebrousedge> You're building on existing knowledge. Crystal and Java are both Object-oriented languages. They're different but not worlds apart
<FromGitter> <Blacksmoke16> structs dont get GC's
<FromGitter> <Blacksmoke16> afaik?
<FromGitter> <randiaz95> hmm
<FromGitter> <randiaz95> why do older people not learn then kai?
<FromGitter> <randiaz95> it's like they stop after school
<FromGitter> <Blacksmoke16> https://github.com/crystal-lang/crystal/issues/7894 might be related to this?
<FromGitter> <Blacksmoke16> er i dont really know
<FromGitter> <Blacksmoke16> guess ill just make my controllers classes for now ha
<FromGitter> <tenebrousedge> I think everyone learns all the time, but studying a specific topic isn't something that everyone finds to be fun
<FromGitter> <tenebrousedge> if learning is the integration of experience, then it would be impossible for most humans not to learn
JuanMiguel has quit [Quit: This computer has gone to sleep]
<FromGitter> <Blacksmoke16> did a benchmark struct vs class controllers
<FromGitter> <Blacksmoke16> classes were 40k requests/sec faster
<FromGitter> <Blacksmoke16> ill take it
JuanMiguel has joined #crystal-lang
<FromGitter> <Blacksmoke16> https://github.com/crystal-lang/crystal/issues/8584 i made an issue for it
<FromGitter> <Blacksmoke16> @dscottboggs_gitlab https://github.com/crystal-lang/crystal/issues/6996 fix this one first 😉
JuanMiguel has quit [Quit: Saliendo]
<FromGitter> <dscottboggs_gitlab> I have no idea what's happening there lol
<FromGitter> <Blacksmoke16> Yet*
<FromGitter> <dscottboggs_gitlab> > did a benchmark struct vs class controllersclasses were 40k requests/sec faster
<FromGitter> <dscottboggs_gitlab> or why structs don't allow finalize/destructor methods :/
<FromGitter> <randiaz95> Lol. @tenebrousedge I think that learning through one's own experience is bad, but learning through others experience is good
<Yxhuvud> re 8584, isn't that basically a use after free? Don't do that, or make certain you have the struct around (on the stack, perhaps)
<FromGitter> <randiaz95> @dscottboggs_gitlab aren't structs just classes without methods outside of initialize?
<FromGitter> <randiaz95> it does seem superfluous.
<FromGitter> <Blacksmoke16> Yxhuvud: probably
<Yxhuvud> randiaz95: no, structs are stack allocated. Meaning when the stackframe is gone that proc will refer back to nonsense.
<FromGitter> <Blacksmoke16> might be able to have some more helpful message vs a segfault tho?
<FromGitter> <manveru> is there some recommended way to compile a plain text file as a string into the binary?
<FromGitter> <manveru> something like `FOO = File.read("./foo")`, but without needing it at runtime
<FromGitter> <tenebrousedge> I think you could do that using a macro
<FromGitter> <tenebrousedge> that should be a compile-time thing
<FromGitter> <tenebrousedge> https://crystal-lang.org/api/0.32.0/Crystal/Macros.html#read_file(filename):StringLiteral-instance-method
<FromGitter> <manveru> ah, thank you very much :)
ur5us has joined #crystal-lang
f1refly has joined #crystal-lang
<FromGitter> <randiaz95> Hey Kai
<FromGitter> <tenebrousedge> yo
<FromGitter> <randiaz95> do you know how to do the equivalent of gsub or string["replacestr"] = "something"
<FromGitter> <randiaz95> in crystal?
<FromGitter> <randiaz95> but i couldnt find any methods
<FromGitter> <Blacksmoke16> its gsub
<FromGitter> <tenebrousedge> There's `sub` and `gsub`
<FromGitter> <Blacksmoke16> https://crystal-lang.org/api/master/String.html#gsub(string:String,replacement)-instance-method
<FromGitter> <randiaz95> interesting....
<FromGitter> <randiaz95> ``` players = players + 1 ⏎ client.gsub("{{id}}", players.to_s) ⏎ client`````` [https://gitter.im/crystal-lang/crystal?at=5df6a3a57ce7ea1e358da4d2]
<FromGitter> <randiaz95> I tried to read a file and replace something
<FromGitter> <randiaz95> in a http handler
<FromGitter> <randiaz95> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5df6a3d655d9392300183007]
<FromGitter> <randiaz95> it didnt work
<FromGitter> <Blacksmoke16> any error/what was the result?
<FromGitter> <randiaz95> must it be a regex?
<FromGitter> <tenebrousedge> no
<FromGitter> <randiaz95> it failed silently
<FromGitter> <randiaz95> just left {{id}} as is
<FromGitter> <randiaz95> and returned the data.
<FromGitter> <tenebrousedge> `gsub` doesn't mutate its caller
<FromGitter> <randiaz95> ah. it returns
<FromGitter> <randiaz95> not inplace mutation
<FromGitter> <randiaz95> gotcha
<FromGitter> <tenebrousedge> strings are immutable
<FromGitter> <randiaz95> When I return client.gsub("{{id}}", players.to_s i get Error: can't return from captured block, use next
<FromGitter> <randiaz95> it works when I create a new variable
<FromGitter> <Blacksmoke16> right, so use `next` instead of `return`? :p
<FromGitter> <randiaz95> Sowy I newb with next
<FromGitter> <tenebrousedge> you may not need to use `return` or `next`, not sure what the context there is
<FromGitter> <tenebrousedge> generally `return` should only be used for early returns
<FromGitter> <randiaz95> I see.
<FromGitter> <tenebrousedge> it should *not* be used just because you want to be explicit that you're returning something
<FromGitter> <randiaz95> Yeah I kind of enjoy not using return
<FromGitter> <randiaz95> Thought it was a feature
<FromGitter> <tenebrousedge> :plus1:
<FromGitter> <randiaz95> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5df6a5be42784416abf2a56a]
<FromGitter> <randiaz95> Seems like I cant return client.gsub though, I need to make a new var `output = client.gsub(...)` then return output on the final line for it to work.
<FromGitter> <randiaz95> Lol I feel so cool with Kemal, it returns how many microseconds a request/response routine took
<FromGitter> <Blacksmoke16> pretty sure that should work
<FromGitter> <Blacksmoke16> any reason not to use a templating lang? or ECR tho?
<FromGitter> <randiaz95> I just don't want to learn that yet :(
<FromGitter> <randiaz95> Want to make sure I know how to use the basic syntax of crystal
<FromGitter> <Blacksmoke16> fair enough
<FromGitter> <Blacksmoke16> where does the `players` var come from in your example?
<FromGitter> <Blacksmoke16> another method or something?
<FromGitter> <tenebrousedge> Plug for the site I mentor people in Crystal at: https://exercism.io/tracks/crystal
<FromGitter> <tenebrousedge> for free, of course
<FromGitter> <randiaz95> I completely changed it blacksmoke
<FromGitter> <randiaz95> lol.. I used to have a global players variable initialized at 0
<FromGitter> <randiaz95> but now I have an array of player objects and i am calculating the id based on the length of previous players
<FromGitter> <Blacksmoke16> prob not ideal
<FromGitter> <Blacksmoke16> in regards to the global var ^
<FromGitter> <randiaz95> its a simple game im making for christmas so shouldnt have deadlocks
<FromGitter> <randiaz95> probably 5-10 players
<FromGitter> <Blacksmoke16> more so was going to say each request gets executed in its own fiber
<FromGitter> <Blacksmoke16> so be wary of context bleeding between different requests
<FromGitter> <Blacksmoke16> like if using class vars etc
<FromGitter> <randiaz95> Right, each fiber wouldn't fail if im just pushing new values into an array right? players << Player(new_id, new_context)
<FromGitter> <randiaz95> I don't think it will bleed.. But its definitely going to explode because I am sharing x and y values accross all people in a global array lol
<FromGitter> <randiaz95> but we will see it when we get there lol
<FromGitter> <Blacksmoke16> no, but it *could* be possible that one request adds its value, does some work, then goes to access that value but another request added its own player object
<FromGitter> <Blacksmoke16> so the first request gest the 2nd request's player obj
<FromGitter> <Blacksmoke16> idk if that would actually happen in your code, just that its possible
<FromGitter> <randiaz95> oh man.
<FromGitter> <randiaz95> that sounds intense.
<FromGitter> <Blacksmoke16> thats the main issue of most of the DI shards out there, they use class vars so one request can mutate a service that another request is using as well
<FromGitter> <randiaz95> I see.. this is the benefit of immutable parallelism from functional languages
ht_ has quit [Quit: ht_]
<FromGitter> <randiaz95> instead of using the object's attribute, i am just making a copy of the variable in the routine
<FromGitter> <randiaz95> hmm.. What if I just keep all the state in the clients and constantly broadcast the current data?
<FromGitter> <randiaz95> instead of storing x and y data into the objects in the server?
<FromGitter> <Blacksmoke16> are your routes authed?
<FromGitter> <Blacksmoke16> and im assuming this is like server rendered stuff vs json api?
<FromGitter> <randiaz95> Nope, its gonna run on the wifi for christmas so you must have access to the wifi password
<FromGitter> <Blacksmoke16> fair
<FromGitter> <randiaz95> well I was thinking of making a quick proprietary pipe delimited string
<FromGitter> <randiaz95> I want to make it json next to learn that
<FromGitter> <randiaz95> then learn how I would implement auth in a json api
<FromGitter> <randiaz95> maybe some token
<FromGitter> <Blacksmoke16> auth in json api is easy
<FromGitter> <Blacksmoke16> jwt token
<FromGitter> <randiaz95> yep thats what everyone says but I never implemented jwt lol
<FromGitter> <randiaz95> I am guessing there is username and password is hashed into a header right?
<FromGitter> <randiaz95> session header*
<FromGitter> <Blacksmoke16> its signed by a secure key
<FromGitter> <Blacksmoke16> but not encrypted
<FromGitter> <Blacksmoke16> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5df6ad71f1cc6c27ea565334]
<FromGitter> <Blacksmoke16> would be something like this
<FromGitter> <Blacksmoke16> the body would be a JSON object that can have anything you want
<FromGitter> <Blacksmoke16> usually like `{"user_id":1}`
<FromGitter> <Blacksmoke16> that you can use to lookup a user from the db or whatever
<FromGitter> <randiaz95> Wow
<FromGitter> <randiaz95> so the secure key doesn't tell the server what id it is?
<FromGitter> <Blacksmoke16> its meant to be stateless
<FromGitter> <Blacksmoke16> so the server doesnt store any information about the request, i.e. the token must be included on every request
<FromGitter> <Blacksmoke16> yea the secure key just signs the token, so that if its tampered with it would know
<FromGitter> <Blacksmoke16> https://jwt.io/introduction/
<FromGitter> <randiaz95> so how do you know if the requesting computer is allowed to see that data?
<FromGitter> <randiaz95> like if i log in to facebook, i can't request another persons page
<FromGitter> <Blacksmoke16> jwt is mainly ment for authentication
<FromGitter> <Blacksmoke16> i.e. it allows you to know who a jwt token belongs to, if they have permission to do whatever is up to the implementer
<FromGitter> <Blacksmoke16> you *could* encode permissions into the token
<FromGitter> <Blacksmoke16> i.e. SSO scopes
<FromGitter> <randiaz95> interesting
<FromGitter> <Blacksmoke16> im more used to rest api/separate front end versus server rendered sites tho
<FromGitter> <Blacksmoke16> way i would do it with separate backend/frontend is like a sign on page if successful sets a cookie with all the security stuff, lax, secure, http only etc
<FromGitter> <Blacksmoke16> the front end js code does a query whenever it loads to like `/user/me`
<FromGitter> <Blacksmoke16> if it fails due to a 401, redirect to the login page
<FromGitter> <Blacksmoke16> otherwise that endpoint returns user info/permissions/roles and stuff
<FromGitter> <Blacksmoke16> that is stored in the js for that session
<FromGitter> <Blacksmoke16> request* not query
<FromGitter> <Blacksmoke16> the `/user/me` would have to be implemented on a low level, so its the first thing that happens, like during bootstrap
<FromGitter> <dscottboggs_gitlab> ☝️ December 15, 2019 4:37 PM (https://gitter.im/crystal-lang/crystal?at=5df6a7a67d382b523f8300b1) I also mentor here
<FromGitter> <randiaz95> Interesting...
<FromGitter> <randiaz95> Blacksmoke has been holding my hand lol
<FromGitter> <randiaz95> Very little doc reading
<FromGitter> <randiaz95> I appreciate it.
<FromGitter> <dscottboggs_gitlab> also regarding JWT I made https://github.com/dscottboggs/kemal-jwt-auth
<FromGitter> <Blacksmoke16> i did a lot of thinking/research on that solution for some side projects :p
<FromGitter> <Blacksmoke16> from what i can tell its the most secure solution
DeBot has quit [Quit: Crystal IRC]
<FromGitter> <dscottboggs_gitlab> JWT or do you mean specifically the Athena implementation of JWT?
asterite has quit [Quit: Bye]
jhass has quit [Quit: Bye]
<FromGitter> <Blacksmoke16> neither, ☝️ December 15, 2019 5:15 PM (https://gitter.im/crystal-lang/crystal?at=5df6b07555d939230018850f)
<FromGitter> <Blacksmoke16> best implementation of jwt auth
<FromGitter> <Blacksmoke16> framework agnostic
<FromGitter> <dscottboggs_gitlab> oh
<FromGitter> <dscottboggs_gitlab> yes
<FromGitter> <dscottboggs_gitlab> I agree wholeheartedly
<FromGitter> <Blacksmoke16> athena doesnt have any security stuff built in atm
<FromGitter> <Blacksmoke16> only real risk is someone getting your jwt token
<FromGitter> <randiaz95> How does one high jack a session to get that token?
<FromGitter> <Blacksmoke16> i was more so thinking like physical access to your computer ;P
<FromGitter> <randiaz95> Lol.. thats more simple..
<FromGitter> <randiaz95> I was imagining a satellite dish accepting wifi signals lol
<FromGitter> <Blacksmoke16> secure only so they couldnt catch it intransit (assuming certs and stuff are setup correclty)
<FromGitter> <randiaz95> intercept the binary and decompile or something
DeBot has joined #crystal-lang
<FromGitter> <Blacksmoke16> http only, so js cant access it
<FromGitter> <randiaz95> right decrypt
<FromGitter> <randiaz95> https
asterite has joined #crystal-lang
<FromGitter> <dscottboggs_gitlab> In fact, I recently did a project for work that started off with a hybrid server- and client-rendered web-ui and I wound up quickly finding it easier to migrate to only client-rendered, especially when dealing with auth. You just *need* it for some interactive elements and once you've got some client-rendered stuff it's just easier to go all the way
<FromGitter> <Blacksmoke16> lax cross domain so CSRF attacks are pretty much prevented
<FromGitter> <dscottboggs_gitlab> > https ⏎ ⏎ yes this prevents your *satellite intercepting wifi signals* concern, unless you transmit your JWT on HTTP (not -S) and then you're firesheeped
<FromGitter> <Blacksmoke16> im personally a fan of the separate client/server
<FromGitter> <randiaz95> well I mean its 2020, so we can use our phones as "satellite dishes" right? lol
<FromGitter> <Blacksmoke16> less work for the server, more flexible as you can change/add api langs etc or vice versa without affecting the other
jhass has joined #crystal-lang
<FromGitter> <Blacksmoke16> plus front end frameworks are quite powerful
<FromGitter> <Blacksmoke16> each has their pros and cons tho
<FromGitter> <dscottboggs_gitlab> yeah but then you're stuck doing your view-models in javascript :(
<FromGitter> <Blacksmoke16> typescript ^
<FromGitter> <Blacksmoke16> 😉
<FromGitter> <dscottboggs_gitlab> I have had some negative experiences with TS
<FromGitter> <Blacksmoke16> oh?
<FromGitter> <Blacksmoke16> im a big fan of it
<FromGitter> <dscottboggs_gitlab> idk maybe I just didn't put enough effort into it... or maybe I was using it alongside the wrong library... but I've run into issues sometimes where basically I track it down on stack exchange and it's like "well JS devs don't have this problem" and it's just like...okay, I guess I'll just use that then
<FromGitter> <dscottboggs_gitlab> Kotlin would be nice, but I feel like I'd run into the same issue x100
<FromGitter> <Blacksmoke16> i mean ts is essentially just typed js
<FromGitter> <Blacksmoke16> same issues id imagine ruby to crystal would have?
<FromGitter> <randiaz95> blacksmoke, so you do your clientside webapps in typescript?
<FromGitter> <Blacksmoke16> im a big fan of https://angular.io/ as well
<FromGitter> <Blacksmoke16> which uses tss
<FromGitter> <dscottboggs_gitlab> idk maybe I should give it another shot
<FromGitter> <dscottboggs_gitlab> last time I tried was with svelte which is pretty bleeding edge, and before that was react, which is pretty insanely complicated. But lately I've been getting into vue which seems to strike the middle between the two
<FromGitter> <Blacksmoke16> friend at work really likes vue
<FromGitter> <tenebrousedge> I would not really call Typescript 'just typed js'
<FromGitter> <Blacksmoke16> *with added features*
<FromGitter> <tenebrousedge> I feel like that's less apropos than calling Crystal 'just typed Ruby'
<FromGitter> <Blacksmoke16> but at a high level thats its main goal
<FromGitter> <nsuchy> haha
<FromGitter> <j8r> I have a good memory of Vue.js
<FromGitter> <nsuchy> it kinda is
<FromGitter> <nsuchy> just different
<FromGitter> <nsuchy> in everyway
<FromGitter> <dscottboggs_gitlab> hey @j8r been a while, good to see you :slight_smile:
<FromGitter> <tenebrousedge> TS has some serious oddities if not downright issues
<FromGitter> <j8r> @dscottboggs_gitlab hello!
<FromGitter> <nsuchy> I mean
<FromGitter> <nsuchy> TS is bad
<FromGitter> <nsuchy> but hey
<FromGitter> <nsuchy> it made VS Code possible
<FromGitter> <nsuchy> everyone loves VS Code
<FromGitter> <Blacksmoke16> > TS is bad ⏎ ⏎ if you say so
<FromGitter> <nsuchy> tehe
<FromGitter> <j8r> perhaps one day they will introduce type annotation in JS, like in Python
<FromGitter> <j8r> but I don't think so
<FromGitter> <nsuchy> they are already considering union types
<FromGitter> <nsuchy> it hasn't been passed yet though
<FromGitter> <j8r> since WASM is coming
<FromGitter> <nsuchy> I think it'll only be warnings though
<FromGitter> <nsuchy> not a complete error out
<FromGitter> <nsuchy> like in crystal
<FromGitter> <nsuchy> or only error out in strict mode
<FromGitter> <dscottboggs_gitlab> that would be better than the situation we have now....
<FromGitter> <Blacksmoke16> now dont get me wrong im not saying you should use TS in place of JS everywhere
<FromGitter> <Blacksmoke16> are for sure cases where js is easier solution
<FromGitter> <nsuchy> i mean
<FromGitter> <nsuchy> tbh im lazy when im writing js
<FromGitter> <Blacksmoke16> but TS is best for larger apps
<FromGitter> <nsuchy> it means I don't want to open a tab and read docs
<FromGitter> <dscottboggs_gitlab> not ok, bud
<FromGitter> <nsuchy> lol
<FromGitter> <j8r> local storage... not known to be easy to deal with
<FromGitter> <Blacksmoke16> is how it works :S
<FromGitter> <nsuchy> we recently started using local storage at work
<FromGitter> <randiaz95> Kinda wish I would learn dart already and write everything in dart
<FromGitter> <randiaz95> for any client
<FromGitter> <dscottboggs_gitlab> meh, I tried out dart for a bit and it felt clumsy
<FromGitter> <nsuchy> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5df6b868dbf24d0becf6f099]
<FromGitter> <Blacksmoke16> localstorage is good for like "should this pane be open or not" etc, but deff not useful for like things that should be secure/confidential
<FromGitter> <nsuchy> we're probably gonna toss the /is_admin fetch request entirely and just set it on login
<FromGitter> <Blacksmoke16> since anyone can just go in and set/change/remove stuff at will
<FromGitter> <j8r> instead of localstorage
<FromGitter> <nsuchy> I mean, the only thing they affect is whether a link is visible
<FromGitter> <nsuchy> you'll get a permissions error if you aren't an admin
<FromGitter> <dscottboggs_gitlab> I use it to cache the JWT, and state that should persist page reloads in an SPA
<FromGitter> <Blacksmoke16> then why not use some permission thing to show it?
<FromGitter> <Blacksmoke16> i mean i guess thats what youre doing already
<FromGitter> <dscottboggs_gitlab> But now I have to literally have checks for `if(token === "undefined" || token === "null" ...` now
<FromGitter> <Blacksmoke16> if `!token`?
<FromGitter> <dscottboggs_gitlab> the string `"undefined"` is truthy
<FromGitter> <Blacksmoke16> fair
<FromGitter> <dscottboggs_gitlab> and like the fact that it's possible for the value `undefined` to just *become* the string `"undefined"` is where I have an issue
<FromGitter> <dscottboggs_gitlab> and with Vue, it's possible to just make *one* component either JS *or* TS, so if I ran into an issue like what I was describing above, that one component could just be written in JS, and for the rest of the app I get the safety benefits TS offers.
<FromGitter> <Blacksmoke16> way we handle it is have a service that wraps localStorage
<FromGitter> <dscottboggs_gitlab> hm, that makes sense
<FromGitter> <dscottboggs_gitlab> but like...it should work right by default haaha
<FromGitter> <Blacksmoke16> that can hold common validation logic, or handle reading/writing objects to it
<FromGitter> <Blacksmoke16> itss a low level api so not quite?
<FromGitter> <nsuchy> I don't like React because its overwhelming
<FromGitter> <nsuchy> wtf is a reducer or redux, how does state or props work
<FromGitter> <dscottboggs_gitlab> localStorage is considered a low-level API? it's literally just a key-value store
<FromGitter> <nsuchy> not any different than redis
<FromGitter> <nsuchy> except its client side and might be slower
<FromGitter> <dscottboggs_gitlab> slower than querying the server over a dodgy wifi or 3g connection?
<FromGitter> <dscottboggs_gitlab> or storing client state on the server-side in some way?
<FromGitter> <nsuchy> fair point
<FromGitter> <nsuchy> I have the luxury of being at nearly no latency high speed networking almost all the time
<FromGitter> <dscottboggs_gitlab> same, but the users of the stuff I write might not haha
<FromGitter> <nsuchy> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5df6bb0bf1cc6c27ea56b3a2]
<FromGitter> <nsuchy> its a bit slow right now
<FromGitter> <nsuchy> lots of people are here and sunday night is primetime
<FromGitter> <nsuchy> normally we're between 10ms and 22ms
ur5us has quit [Ping timeout: 250 seconds]
<FromGitter> <randiaz95> It's crazy how every developer has different opinions about how to get x done but they all can get it done their way.
<FromGitter> <Blacksmoke16> @dscottboggs_gitlab low level in that it doesnt do anything else besides put/get an item
<FromGitter> <Blacksmoke16> no validation or anything
<FromGitter> <j8r> Indexed DB is also a solution, more complicated
<FromGitter> <nsuchy> i mean
<FromGitter> <nsuchy> im just lazy and want money so I'll come up with whatever takes the least time to think of and work to meet minimum expectations and requirements
<FromGitter> <nsuchy> localStorage just works if there's an actual bug caused by its behavior I'll deal with it then
<FromGitter> <nsuchy> meanwhile I've already picked up another project and started coding
<FromGitter> <nsuchy> Crystal and Amber has been amazing and has way less boilerplate stuff than rails
<FromGitter> <j8r> yes but spending a bit more time may be worth it
<FromGitter> <j8r> it's a compromise
<FromGitter> <j8r> between time spent right now and future for fixes
ur5us has joined #crystal-lang
<FromGitter> <nsuchy> it also depends on how much someone is paying and their budget
<FromGitter> <nsuchy> for example I help out a tiny gaming forum with a crystal app I didn't bill them for
<FromGitter> <nsuchy> I'm not too concerned with bugs, they're always free to pay if they need my undivided attention
<FromGitter> <j8r> you will be more concerned if you are on a critical project, and be on duty 24/24 😉
<FromGitter> <j8r> yep, depends of the project
<FromGitter> <j8r> and the managers
<FromGitter> <nsuchy> luckily for me my web app doesn't deal with life or death (like hospital computer systems)
<FromGitter> <j8r> dealing with money is also quite important (not that high, though)
<FromGitter> <nsuchy> you can generally fix a rounding error
<FromGitter> <nsuchy> you can't fix a dead human :{
<FromGitter> <nsuchy> and any substancial amount of money should have more than one developer reviewing the math :P
<FromGitter> <tenebrousedge> Dr Frankenstein begs to differ. Muahahaha!
<FromGitter> <nsuchy> (when ur the only dev working for a small bank)
<FromGitter> <nsuchy> (tiny rounding error despoits into a fake account that leaks to you)
<FromGitter> <nsuchy> (since ur only dev the bank won't find out right)
_whitelogger has joined #crystal-lang
<FromGitter> <randiaz95> lol
<FromGitter> <randiaz95> downloading free game for end of sunday
<FromGitter> <randiaz95> finally going to do something non-educational lol