+5
-5
README.md
+5
-5
README.md
···It's a URL shorten service that uses ATProto so that the users creating the short links will always own the links they are creating and gives them the option to host the service themselves so that they can be sure that the links will always be available.This project was inspired by a conversation with someone about the classic engineering interview question about creating a URL shortning service. One of the downfalls of this is that you're relying on the service to always be there so that your links don't die. I think Google announced that they were shutting down their service which caused uproar because it meant that existing links embeded in websites and other places would cease to work. Thankfully they announced that they would allow existing links to work, just not allow new ones to be created. But that scare of links no longer working, made me think about how the ATProto architecture is perfect for allowing users to own their links and be sure that they will always be available without depending on another service.-When a user logs in with their ATProto account, they will be able to create a new short URL. This action creates a record in their PDS containing the URL to redirect to and in the future could contain other peices of metadata. The key bit here is that the record in their PDS is created with an RKey, which in this application is a TID ((timestamp identifier)[https://atproto.com/specs/tid]) which is unique and that key becomes the "short URL" ID. Combine that with the host that created the ID and you get a short URL. The users DID, key and URL are then stored in a local database to the service.+When a user logs in with their ATProto account, they will be able to create a new short URL. This action creates a record in their PDS containing the URL to redirect to and in the future could contain other peices of metadata. The key bit here is that the record in their PDS is created with an RKey, which in this application is a TID ([timestamp identifier](https://atproto.com/specs/tid)) which is unique and that key becomes the "short URL" ID. Combine that with the host that created the ID and you get a short URL. The users DID, key and URL are then stored in a local database to the service.As long as the service is running at that host, the short URL will be available to be redirected. When the short URL is hit, the service will take the key part of the URL, look it up in the database to find the real URL and then redirect to that URL.···-Another neat part of this architecture is that if a user wants to self host this, they can and the links they create will only work for their service. For example.+Another neat part of this architecture is that it allows the user to self host the service. Traditional short URL services turn out to be a lot of hassle. Read this really interesting [thread on Bluesky](https://bsky.app/profile/gbl08ma.com/post/3m2pft7a3dc23) about it from the creator of [tny.im](tny.im). Turns out hosting one for others to use isn't a great move these days, so by having one that you can host yourself and only you can use, could be a really handy tool. You create the short URLs and pass them out to people to use.+The way the service works, is that whe you start it up, you configure it to be for your DID (ATProto identifier) so that only you can log into the service to create short URLs. Then when the Jetstream consumer runs, it only listens to events for your DID which means you only get your short URL records in the local database.-If I create a short URL `https://my-short-service/a/abcd` on my service and then someone creates `https://a-different-short-service/a/1234` those links will only work with the domain that created them. I wouldn't be able to take the key `abcd` and use it with the `https://a-different-short-service` domain because that isn't the domain that created the link. This means that even though every service is consuming all of the short URL ATProto records, there will never be a case where someone could hijack an ID to redirect to somewhere else without the user that created and owning the link from doing so (because updating a record in a PDS requires the users auth).+Remember!!! All of the links you create are stored in your PDS which is public. So anyone that wants to see what links you've created and go to them, will be able to do that.
+5
auth_handlers.go
+5
auth_handlers.go
+10
-4
cmd/atshorter/main.go
+10
-4
cmd/atshorter/main.go
·········
+2
-2
consumer.go
+2
-2
consumer.go
···+func NewConsumer(jsAddr string, logger *slog.Logger, store HandlerStore, did string) *consumer {···-cfg.WantedDids = []string{} // TODO: possibly when self hosting, limit this to just a select few?
+1
example.env
+1
example.env
+3
-1
server.go
+3
-1
server.go
······-func NewServer(host string, port string, store Store, oauthClient *oauth.ClientApp, httpClient *http.Client) (*Server, error) {+func NewServer(host string, port string, store Store, oauthClient *oauth.ClientApp, httpClient *http.Client, usersDID string) (*Server, error) {···