oauth test
This commit is contained in:
parent
1469545429
commit
c3f5d612c3
|
@ -1,16 +1,14 @@
|
||||||
devbox for shareable development environment tooling
|
devbox for shareable development environment tooling
|
||||||
|
|
||||||
git monorepo for housing separate node packages within a single repository
|
git monorepo for housing separate packages within a single repository (see ./services and ./packages)
|
||||||
|
|
||||||
TypeScript
|
|
||||||
|
|
||||||
pnpm for package management and workspaces (separate node packages.)
|
pnpm for package management and workspaces (separate node packages.)
|
||||||
|
|
||||||
Kubernetes for Development using Tiltfile
|
Phoenix framework
|
||||||
|
|
||||||
Kubernetes for Production, deployed using FluxCD
|
docker-compose for containerized development
|
||||||
|
|
||||||
Kubernetes deployed to Hetzner using https://github.com/kube-hetzner/terraform-hcloud-kube-hetzner
|
Kamal for deployments
|
||||||
|
|
||||||
ggshield for preventing git commits containing secrets
|
ggshield for preventing git commits containing secrets
|
||||||
|
|
||||||
|
|
18
README.md
18
README.md
|
@ -8,16 +8,19 @@ See ./ARCHITECTURE.md for an overview of the infrastructure components.
|
||||||
|
|
||||||
## Getting Started
|
## Getting Started
|
||||||
|
|
||||||
I'm working towards a better development experience with devbox and Tilt. This process is in a state of flux and is likely to be broken.
|
The main gist is as follows.
|
||||||
|
|
||||||
The main gist is as follows
|
1. install [docker](https://docs.docker.com/engine/install) `wget -O- get.docker.com | bash`
|
||||||
|
1. Install [devbox](https://www.jetify.com/devbox/docs/installing_devbox/) `curl -fsSL https://get.jetify.com/devbox | bash`
|
||||||
1. Install [devbox](https://www.jetify.com/devbox/docs/installing_devbox/)
|
|
||||||
2. Install development environment & packages using devbox.
|
2. Install development environment & packages using devbox.
|
||||||
|
|
||||||
devbox install
|
devbox install
|
||||||
|
|
||||||
3.
|
|
||||||
|
3. Run `docker compose up --watch`
|
||||||
|
4. Visit http://localhost:4000
|
||||||
|
|
||||||
|
If all went well, editing source code will automatically affect the website running in your browser.
|
||||||
|
|
||||||
## backup/restore dev database
|
## backup/restore dev database
|
||||||
|
|
||||||
|
@ -38,8 +41,7 @@ Use devbox helper script
|
||||||
|
|
||||||
Keeping track of metrics we want to scrape using Prometheus
|
Keeping track of metrics we want to scrape using Prometheus
|
||||||
|
|
||||||
### Uppy
|
|
||||||
|
|
||||||
https://uppy.fp.sbtp.xyz/metrics
|
|
||||||
|
|
||||||
|
|
||||||
|
|
186
devbox.lock
186
devbox.lock
|
@ -2,150 +2,150 @@
|
||||||
"lockfile_version": "1",
|
"lockfile_version": "1",
|
||||||
"packages": {
|
"packages": {
|
||||||
"ffmpeg@latest": {
|
"ffmpeg@latest": {
|
||||||
"last_modified": "2024-07-24T00:53:51Z",
|
"last_modified": "2025-01-07T09:15:50Z",
|
||||||
"resolved": "github:NixOS/nixpkgs/4f02464258baaf54992debfd010a7a3662a25536#ffmpeg",
|
"resolved": "github:NixOS/nixpkgs/8c9fd3e564728e90829ee7dbac6edc972971cd0f#ffmpeg",
|
||||||
"source": "devbox-search",
|
"source": "devbox-search",
|
||||||
"version": "6.1.1",
|
"version": "7.1",
|
||||||
"systems": {
|
"systems": {
|
||||||
"aarch64-darwin": {
|
"aarch64-darwin": {
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
"name": "bin",
|
"name": "bin",
|
||||||
"path": "/nix/store/7jl394717pnlj5jy8n46jq65sw1gwb20-ffmpeg-6.1.1-bin",
|
"path": "/nix/store/m48ypyjnl04mqigi6fbxa7k2c5bsvazz-ffmpeg-7.1-bin",
|
||||||
"default": true
|
"default": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "man",
|
"name": "man",
|
||||||
"path": "/nix/store/ma1ssbkbwrasdgsyp0y3x6jbc72pp9s7-ffmpeg-6.1.1-man",
|
"path": "/nix/store/10ncvfz8srnzckq16bn14wffcx8j04ki-ffmpeg-7.1-man",
|
||||||
"default": true
|
"default": true
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "out",
|
|
||||||
"path": "/nix/store/smq7vi0562incbgwf4cbx10i0y46jsbc-ffmpeg-6.1.1"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "data",
|
"name": "data",
|
||||||
"path": "/nix/store/289ikv8ld8whmixs3r4qd4r878mkjmm9-ffmpeg-6.1.1-data"
|
"path": "/nix/store/rqbsc9zyzi988hwcd423qdh1vh40zlzc-ffmpeg-7.1-data"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "dev",
|
"name": "dev",
|
||||||
"path": "/nix/store/r8y6va82y6libjw065gkn5gr51715gac-ffmpeg-6.1.1-dev"
|
"path": "/nix/store/6ml3pn92nbmnc40s5jfpr84y65ysizk3-ffmpeg-7.1-dev"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "doc",
|
"name": "doc",
|
||||||
"path": "/nix/store/yasff9ggma6myg47sm805idfxnz0zkac-ffmpeg-6.1.1-doc"
|
"path": "/nix/store/ni6gri7m1pavfjxx0yfj1msvb0cfasgg-ffmpeg-7.1-doc"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "lib",
|
"name": "lib",
|
||||||
"path": "/nix/store/pmv9jg541b2valk47vh7q40m1p8xr7ik-ffmpeg-6.1.1-lib"
|
"path": "/nix/store/2v2rr9dmq4grzwmg4zcsxrmbdcshks7m-ffmpeg-7.1-lib"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "out",
|
||||||
|
"path": "/nix/store/nvccyp4dra8f92ywd00lk3ra121gj162-ffmpeg-7.1"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"store_path": "/nix/store/7jl394717pnlj5jy8n46jq65sw1gwb20-ffmpeg-6.1.1-bin"
|
"store_path": "/nix/store/m48ypyjnl04mqigi6fbxa7k2c5bsvazz-ffmpeg-7.1-bin"
|
||||||
},
|
},
|
||||||
"aarch64-linux": {
|
"aarch64-linux": {
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
"name": "bin",
|
"name": "bin",
|
||||||
"path": "/nix/store/6ydyry316fcc59iy80zpnxnsrh9f18ki-ffmpeg-6.1.1-bin",
|
"path": "/nix/store/lj99z3ldzka2slgm94w2yl8cjkphn4m3-ffmpeg-7.1-bin",
|
||||||
"default": true
|
"default": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "man",
|
"name": "man",
|
||||||
"path": "/nix/store/k1frp52lx3ycwbdgliwcrmb81zm4n10n-ffmpeg-6.1.1-man",
|
"path": "/nix/store/gisda8d2pifrrjw0yirrs0x2cyn6b96i-ffmpeg-7.1-man",
|
||||||
"default": true
|
"default": true
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "dev",
|
|
||||||
"path": "/nix/store/rdh4mv7fnmj79a4dp9rfqnd711y9inpv-ffmpeg-6.1.1-dev"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "doc",
|
|
||||||
"path": "/nix/store/vam8a1591x7bkqjljvwsral2v72xwa77-ffmpeg-6.1.1-doc"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "lib",
|
|
||||||
"path": "/nix/store/k2mdb9lh6qjb63pizcc0lv7kzakgvcm1-ffmpeg-6.1.1-lib"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "out",
|
"name": "out",
|
||||||
"path": "/nix/store/6z17gry0dn1yxr3r36fk87sxnddcjg66-ffmpeg-6.1.1"
|
"path": "/nix/store/pc332zx12j2fqf5m9mdhhs1rwksbk2fk-ffmpeg-7.1"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "data",
|
"name": "data",
|
||||||
"path": "/nix/store/qxyrrzdl4svxs3dfszsmi2mky4vrzvfa-ffmpeg-6.1.1-data"
|
"path": "/nix/store/4yhsn6lrfn91dk1kq9wyyd71p4hcfans-ffmpeg-7.1-data"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "dev",
|
||||||
|
"path": "/nix/store/71103mmkxhzzmbj9mpzsrzbp988z3p98-ffmpeg-7.1-dev"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "doc",
|
||||||
|
"path": "/nix/store/k9cc4d60frcn27zapkzhag5h9r0ig5xa-ffmpeg-7.1-doc"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "lib",
|
||||||
|
"path": "/nix/store/dgcmpc8az51a4d2bxgrmfz8zlmvqxwa5-ffmpeg-7.1-lib"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"store_path": "/nix/store/6ydyry316fcc59iy80zpnxnsrh9f18ki-ffmpeg-6.1.1-bin"
|
"store_path": "/nix/store/lj99z3ldzka2slgm94w2yl8cjkphn4m3-ffmpeg-7.1-bin"
|
||||||
},
|
},
|
||||||
"x86_64-darwin": {
|
"x86_64-darwin": {
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
"name": "bin",
|
"name": "bin",
|
||||||
"path": "/nix/store/84yjd9p94kknxpdn974ksb7y28l6paq4-ffmpeg-6.1.1-bin",
|
"path": "/nix/store/z44kr817zx99vi2cc204i06cnmz83f1n-ffmpeg-7.1-bin",
|
||||||
"default": true
|
"default": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "man",
|
"name": "man",
|
||||||
"path": "/nix/store/r1g3627b14nqpz4aqfp87ba0fh49ar5k-ffmpeg-6.1.1-man",
|
"path": "/nix/store/slrha22nqrx2xw009hd37svv2nvpp26i-ffmpeg-7.1-man",
|
||||||
"default": true
|
"default": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "data",
|
"name": "data",
|
||||||
"path": "/nix/store/dv5lc67c3xykza11q5pwk4vivnsdswmw-ffmpeg-6.1.1-data"
|
"path": "/nix/store/n3xm2rr1k1ari7ysbp9jhg65pih28x6x-ffmpeg-7.1-data"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "dev",
|
"name": "dev",
|
||||||
"path": "/nix/store/f0qcama09w9kri8hqvn0lk89zck4978v-ffmpeg-6.1.1-dev"
|
"path": "/nix/store/59gcv4rfg38rqnazv1iq9jssjak2l3ih-ffmpeg-7.1-dev"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "doc",
|
"name": "doc",
|
||||||
"path": "/nix/store/7sg26fama7a6gpdm0kkphblzc2x03dfx-ffmpeg-6.1.1-doc"
|
"path": "/nix/store/2cqa3lc75ciqzgmxjm36fd733f3gjgil-ffmpeg-7.1-doc"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "lib",
|
"name": "lib",
|
||||||
"path": "/nix/store/rhq35qgr8yvhygpj24wm14anidf9gmmc-ffmpeg-6.1.1-lib"
|
"path": "/nix/store/ir47x8skj54wilcyz2x59am4y085lf6l-ffmpeg-7.1-lib"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "out",
|
"name": "out",
|
||||||
"path": "/nix/store/31q5qklv5jmv91sjs4ljmq45smi7ngxy-ffmpeg-6.1.1"
|
"path": "/nix/store/gqw958wdgrbfsxczqf56vnq1iffg5qv1-ffmpeg-7.1"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"store_path": "/nix/store/84yjd9p94kknxpdn974ksb7y28l6paq4-ffmpeg-6.1.1-bin"
|
"store_path": "/nix/store/z44kr817zx99vi2cc204i06cnmz83f1n-ffmpeg-7.1-bin"
|
||||||
},
|
},
|
||||||
"x86_64-linux": {
|
"x86_64-linux": {
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
"name": "bin",
|
"name": "bin",
|
||||||
"path": "/nix/store/wnmy246m582splkkqwpgza390sa4m1k1-ffmpeg-6.1.1-bin",
|
"path": "/nix/store/d1lv3x7iq129vb19ba9ph6k0yhy4fv34-ffmpeg-7.1-bin",
|
||||||
"default": true
|
"default": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "man",
|
"name": "man",
|
||||||
"path": "/nix/store/hqq9mmrwrbazfdcsmd2dd3jgpvpsyj5p-ffmpeg-6.1.1-man",
|
"path": "/nix/store/qqgvvfw2gqp47zl5v9jhdsl8mb77l909-ffmpeg-7.1-man",
|
||||||
"default": true
|
"default": true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "doc",
|
||||||
|
"path": "/nix/store/gmfj9af6za9i2830cgbj1qazz2nir2vs-ffmpeg-7.1-doc"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "lib",
|
"name": "lib",
|
||||||
"path": "/nix/store/5jynrssm1bvrj3kskwgyyhb2069f8dwv-ffmpeg-6.1.1-lib"
|
"path": "/nix/store/x8j2nr5qmikfaggl34wpm1dlldb7ik06-ffmpeg-7.1-lib"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "out",
|
"name": "out",
|
||||||
"path": "/nix/store/xdb4w2ccvig6020ish7qpl88i8fqg2ai-ffmpeg-6.1.1"
|
"path": "/nix/store/cx89mypnxgk0q4dibacg7dsrb4w66mv9-ffmpeg-7.1"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "data",
|
"name": "data",
|
||||||
"path": "/nix/store/sw8wxzscsnxnvrwqzq4fqxvggcd1xic7-ffmpeg-6.1.1-data"
|
"path": "/nix/store/5y8zk8fqpaammsnz2svgpdsayn4zlsn2-ffmpeg-7.1-data"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "dev",
|
"name": "dev",
|
||||||
"path": "/nix/store/p6jd7041xggbkwyfzrgsm8ccj370w1hz-ffmpeg-6.1.1-dev"
|
"path": "/nix/store/qdz8aidi7rksr4g5cpxgz9iivrlsa247-ffmpeg-7.1-dev"
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "doc",
|
|
||||||
"path": "/nix/store/1dfla14f5g5xwmw3w5cjfnwdfr64qw7z-ffmpeg-6.1.1-doc"
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"store_path": "/nix/store/wnmy246m582splkkqwpgza390sa4m1k1-ffmpeg-6.1.1-bin"
|
"store_path": "/nix/store/d1lv3x7iq129vb19ba9ph6k0yhy4fv34-ffmpeg-7.1-bin"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -246,124 +246,124 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nodejs@20": {
|
"nodejs@20": {
|
||||||
"last_modified": "2024-07-07T07:43:47Z",
|
"last_modified": "2024-12-23T21:10:33Z",
|
||||||
"plugin_version": "0.0.2",
|
"plugin_version": "0.0.2",
|
||||||
"resolved": "github:NixOS/nixpkgs/b60793b86201040d9dee019a05089a9150d08b5b#nodejs_20",
|
"resolved": "github:NixOS/nixpkgs/de1864217bfa9b5845f465e771e0ecb48b30e02d#nodejs_20",
|
||||||
"source": "devbox-search",
|
"source": "devbox-search",
|
||||||
"version": "20.14.0",
|
"version": "20.18.1",
|
||||||
"systems": {
|
"systems": {
|
||||||
"aarch64-darwin": {
|
"aarch64-darwin": {
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
"name": "out",
|
"name": "out",
|
||||||
"path": "/nix/store/sqnbldm1fjw88v23yq4v6531y4m7v2fh-nodejs-20.14.0",
|
"path": "/nix/store/q49zbi0pzjhg4zn085h9hyz9m1k3hvpb-nodejs-20.18.1",
|
||||||
"default": true
|
"default": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "libv8",
|
"name": "libv8",
|
||||||
"path": "/nix/store/1i0rb2axkrxvsq5pz8s2q07ard2p36a1-nodejs-20.14.0-libv8"
|
"path": "/nix/store/l08rljd2yr7i1q4x778qazcys2l4ja23-nodejs-20.18.1-libv8"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"store_path": "/nix/store/sqnbldm1fjw88v23yq4v6531y4m7v2fh-nodejs-20.14.0"
|
"store_path": "/nix/store/q49zbi0pzjhg4zn085h9hyz9m1k3hvpb-nodejs-20.18.1"
|
||||||
},
|
},
|
||||||
"aarch64-linux": {
|
"aarch64-linux": {
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
"name": "out",
|
"name": "out",
|
||||||
"path": "/nix/store/r1nwmlbsn67f5rhayr7jjjdmiflxpk92-nodejs-20.14.0",
|
"path": "/nix/store/4m1ql1hsd6kqmzr8a657qhipjgssrr0c-nodejs-20.18.1",
|
||||||
"default": true
|
"default": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "libv8",
|
"name": "libv8",
|
||||||
"path": "/nix/store/5ii3xkbd3iv0xvqqvjg3agsm0dinidgm-nodejs-20.14.0-libv8"
|
"path": "/nix/store/r8s1xalb4rpy1r44i413j84i4ny6mnsc-nodejs-20.18.1-libv8"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"store_path": "/nix/store/r1nwmlbsn67f5rhayr7jjjdmiflxpk92-nodejs-20.14.0"
|
"store_path": "/nix/store/4m1ql1hsd6kqmzr8a657qhipjgssrr0c-nodejs-20.18.1"
|
||||||
},
|
},
|
||||||
"x86_64-darwin": {
|
"x86_64-darwin": {
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
"name": "out",
|
"name": "out",
|
||||||
"path": "/nix/store/wzgnws4r1c98vzj5q6gq4drz2jfq7d5q-nodejs-20.14.0",
|
"path": "/nix/store/7ky0mn6k33731jwzhsxq6a6dsbjqamqs-nodejs-20.18.1",
|
||||||
"default": true
|
"default": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "libv8",
|
"name": "libv8",
|
||||||
"path": "/nix/store/gc2gnkc8hvkh51ab3a29fvgzy2qsqb2s-nodejs-20.14.0-libv8"
|
"path": "/nix/store/jw62k3wxl38r8fcbvxaxrm696ivv3imr-nodejs-20.18.1-libv8"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"store_path": "/nix/store/wzgnws4r1c98vzj5q6gq4drz2jfq7d5q-nodejs-20.14.0"
|
"store_path": "/nix/store/7ky0mn6k33731jwzhsxq6a6dsbjqamqs-nodejs-20.18.1"
|
||||||
},
|
},
|
||||||
"x86_64-linux": {
|
"x86_64-linux": {
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
"name": "out",
|
"name": "out",
|
||||||
"path": "/nix/store/ilkfhnqz4xczrliqjva8770x2svbfznd-nodejs-20.14.0",
|
"path": "/nix/store/j7dx1n6m5axf9r2bvly580x2ixx546wq-nodejs-20.18.1",
|
||||||
"default": true
|
"default": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "libv8",
|
"name": "libv8",
|
||||||
"path": "/nix/store/2qaf68dzimr8as4bgli0xmsn11c0ah2j-nodejs-20.14.0-libv8"
|
"path": "/nix/store/qljmc2skrldj0g94rib6nl4jq84193fa-nodejs-20.18.1-libv8"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"store_path": "/nix/store/ilkfhnqz4xczrliqjva8770x2svbfznd-nodejs-20.14.0"
|
"store_path": "/nix/store/j7dx1n6m5axf9r2bvly580x2ixx546wq-nodejs-20.18.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"python310@latest": {
|
"python310@latest": {
|
||||||
"last_modified": "2024-07-07T07:43:47Z",
|
"last_modified": "2024-12-23T21:10:33Z",
|
||||||
"plugin_version": "0.0.4",
|
"plugin_version": "0.0.4",
|
||||||
"resolved": "github:NixOS/nixpkgs/b60793b86201040d9dee019a05089a9150d08b5b#python310",
|
"resolved": "github:NixOS/nixpkgs/de1864217bfa9b5845f465e771e0ecb48b30e02d#python310",
|
||||||
"source": "devbox-search",
|
"source": "devbox-search",
|
||||||
"version": "3.10.14",
|
"version": "3.10.16",
|
||||||
"systems": {
|
"systems": {
|
||||||
"aarch64-darwin": {
|
"aarch64-darwin": {
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
"name": "out",
|
"name": "out",
|
||||||
"path": "/nix/store/n0gcjj86qjx7w59bwpzqvzdwrjdc7bwy-python3-3.10.14",
|
"path": "/nix/store/382cajdyw7qsgrzjf8y79hssg8ggv18x-python3-3.10.16",
|
||||||
"default": true
|
"default": true
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"store_path": "/nix/store/n0gcjj86qjx7w59bwpzqvzdwrjdc7bwy-python3-3.10.14"
|
"store_path": "/nix/store/382cajdyw7qsgrzjf8y79hssg8ggv18x-python3-3.10.16"
|
||||||
},
|
},
|
||||||
"aarch64-linux": {
|
"aarch64-linux": {
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
"name": "out",
|
"name": "out",
|
||||||
"path": "/nix/store/pzpn4j6hh8ayy15cb36s7i8v0mkavy0z-python3-3.10.14",
|
"path": "/nix/store/bvvky8yghyl23vwdhf6dmq6w1a4nm1mg-python3-3.10.16",
|
||||||
"default": true
|
"default": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "debug",
|
"name": "debug",
|
||||||
"path": "/nix/store/h873y0nbzqlmsda6m2vfdcjw1v6c660f-python3-3.10.14-debug"
|
"path": "/nix/store/msw7k25qw8wfqjrdv6j2sydqxddmaw32-python3-3.10.16-debug"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"store_path": "/nix/store/pzpn4j6hh8ayy15cb36s7i8v0mkavy0z-python3-3.10.14"
|
"store_path": "/nix/store/bvvky8yghyl23vwdhf6dmq6w1a4nm1mg-python3-3.10.16"
|
||||||
},
|
},
|
||||||
"x86_64-darwin": {
|
"x86_64-darwin": {
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
"name": "out",
|
"name": "out",
|
||||||
"path": "/nix/store/3ia1741fyzlcjgp3kg01hlk3z1jlp9x0-python3-3.10.14",
|
"path": "/nix/store/2dnz9rwscr6d1pma8h5q7ckfavsrvhb1-python3-3.10.16",
|
||||||
"default": true
|
"default": true
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"store_path": "/nix/store/3ia1741fyzlcjgp3kg01hlk3z1jlp9x0-python3-3.10.14"
|
"store_path": "/nix/store/2dnz9rwscr6d1pma8h5q7ckfavsrvhb1-python3-3.10.16"
|
||||||
},
|
},
|
||||||
"x86_64-linux": {
|
"x86_64-linux": {
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
"name": "out",
|
"name": "out",
|
||||||
"path": "/nix/store/handws5bj8l411asgs68s3bj8f05qnn5-python3-3.10.14",
|
"path": "/nix/store/rv4ykblb2w9qc7w7a10dbw4r1am7zm9n-python3-3.10.16",
|
||||||
"default": true
|
"default": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "debug",
|
"name": "debug",
|
||||||
"path": "/nix/store/sl3yyz93mar0jk6cnw0lqv4xrvsbas0a-python3-3.10.14-debug"
|
"path": "/nix/store/l0fx7jgxq5pn27n74haq9c5bhwvbkpab-python3-3.10.16-debug"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"store_path": "/nix/store/handws5bj8l411asgs68s3bj8f05qnn5-python3-3.10.14"
|
"store_path": "/nix/store/rv4ykblb2w9qc7w7a10dbw4r1am7zm9n-python3-3.10.16"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -518,66 +518,66 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"yt-dlp@latest": {
|
"yt-dlp@latest": {
|
||||||
"last_modified": "2024-07-18T22:08:26Z",
|
"last_modified": "2025-01-03T14:51:55Z",
|
||||||
"resolved": "github:NixOS/nixpkgs/cfa5366588c940ab6ee3bee399b337175545c664#yt-dlp",
|
"resolved": "github:NixOS/nixpkgs/a27871180d30ebee8aa6b11bf7fef8a52f024733#yt-dlp",
|
||||||
"source": "devbox-search",
|
"source": "devbox-search",
|
||||||
"version": "2024.7.16",
|
"version": "2024.12.23",
|
||||||
"systems": {
|
"systems": {
|
||||||
"aarch64-darwin": {
|
"aarch64-darwin": {
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
"name": "out",
|
"name": "out",
|
||||||
"path": "/nix/store/sb1129rd65qynmf5pqshr2885g54hjdz-python3.12-yt-dlp-2024.7.16",
|
"path": "/nix/store/8fmy039278i7q31zyyrfmr4z5k35xvp6-yt-dlp-2024.12.23",
|
||||||
"default": true
|
"default": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "dist",
|
"name": "dist",
|
||||||
"path": "/nix/store/7c75jyvxvqhnhlb8iv99m0m2gzaz1562-python3.12-yt-dlp-2024.7.16-dist"
|
"path": "/nix/store/v9mplambvs7hlcpcpnvmf7c30pk5cx8d-yt-dlp-2024.12.23-dist"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"store_path": "/nix/store/sb1129rd65qynmf5pqshr2885g54hjdz-python3.12-yt-dlp-2024.7.16"
|
"store_path": "/nix/store/8fmy039278i7q31zyyrfmr4z5k35xvp6-yt-dlp-2024.12.23"
|
||||||
},
|
},
|
||||||
"aarch64-linux": {
|
"aarch64-linux": {
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
"name": "out",
|
"name": "out",
|
||||||
"path": "/nix/store/rzr6pr2axf653258rnlrldx540wag1h0-python3.12-yt-dlp-2024.7.16",
|
"path": "/nix/store/wzna2q40a81qj4icma4q20q9fjg9md76-yt-dlp-2024.12.23",
|
||||||
"default": true
|
"default": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "dist",
|
"name": "dist",
|
||||||
"path": "/nix/store/js7w9zzcydsf020njvhy3dbvarv4c9qj-python3.12-yt-dlp-2024.7.16-dist"
|
"path": "/nix/store/z0b0nv6a2wl0565f5ffrzhg2zcqflvrl-yt-dlp-2024.12.23-dist"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"store_path": "/nix/store/rzr6pr2axf653258rnlrldx540wag1h0-python3.12-yt-dlp-2024.7.16"
|
"store_path": "/nix/store/wzna2q40a81qj4icma4q20q9fjg9md76-yt-dlp-2024.12.23"
|
||||||
},
|
},
|
||||||
"x86_64-darwin": {
|
"x86_64-darwin": {
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
"name": "out",
|
"name": "out",
|
||||||
"path": "/nix/store/q3sqpq348nj1zhlwsfmbwcqnmkfglmlj-python3.12-yt-dlp-2024.7.16",
|
"path": "/nix/store/mpbp9jar45hk22ddldm0bbk60vz5w643-yt-dlp-2024.12.23",
|
||||||
"default": true
|
"default": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "dist",
|
"name": "dist",
|
||||||
"path": "/nix/store/f6i4bq4fbcd1s7k660fkqr15g0lzrfvx-python3.12-yt-dlp-2024.7.16-dist"
|
"path": "/nix/store/gq4l9yfs7fjb05qkl97hmsq69s3k4shr-yt-dlp-2024.12.23-dist"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"store_path": "/nix/store/q3sqpq348nj1zhlwsfmbwcqnmkfglmlj-python3.12-yt-dlp-2024.7.16"
|
"store_path": "/nix/store/mpbp9jar45hk22ddldm0bbk60vz5w643-yt-dlp-2024.12.23"
|
||||||
},
|
},
|
||||||
"x86_64-linux": {
|
"x86_64-linux": {
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
"name": "out",
|
"name": "out",
|
||||||
"path": "/nix/store/m47znwi2bc09g66j2kn6k7fvfx9cvr38-python3.12-yt-dlp-2024.7.16",
|
"path": "/nix/store/wqcs5crm36p603fkh9j2k868zzb8q79c-yt-dlp-2024.12.23",
|
||||||
"default": true
|
"default": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "dist",
|
"name": "dist",
|
||||||
"path": "/nix/store/7laiz6ilsx4xzk6xni7yl8g3g04wyl55-python3.12-yt-dlp-2024.7.16-dist"
|
"path": "/nix/store/j452c5bii2slx1biix7lfc5k0aqg2rvs-yt-dlp-2024.12.23-dist"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"store_path": "/nix/store/m47znwi2bc09g66j2kn6k7fvfx9cvr38-python3.12-yt-dlp-2024.7.16"
|
"store_path": "/nix/store/wqcs5crm36p603fkh9j2k868zzb8q79c-yt-dlp-2024.12.23"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,17 +76,36 @@ services:
|
||||||
- db
|
- db
|
||||||
# volumes:
|
# volumes:
|
||||||
# - ./services/bright/lib:/app/lib
|
# - ./services/bright/lib:/app/lib
|
||||||
|
# volumes:
|
||||||
|
# - /home/cj/Documents/ueberauth_patreon:/app/contrib/ueberauth_patreon
|
||||||
develop:
|
develop:
|
||||||
watch:
|
watch:
|
||||||
- action: sync
|
- path: ./services/bright/
|
||||||
path: ./services/bright/
|
|
||||||
target: /app/
|
target: /app/
|
||||||
- action: sync+restart
|
action: sync
|
||||||
path: ./services/bright/application.ex
|
- path: ./services/bright/application.ex
|
||||||
target: /app/lib/bright/application.ex
|
target: /app/lib/bright/application.ex
|
||||||
- action: sync+restart
|
action: sync+restart
|
||||||
path: ./services/bright/mix.exs
|
- path: ./services/bright/config/config.exs
|
||||||
|
target: /app/lib/bright/config/config.exs
|
||||||
|
action: sync+restart
|
||||||
|
- path: ./services/bright/config/runtime.exs
|
||||||
|
target: /app/lib/bright/config/runtime.exs
|
||||||
|
action: sync+restart
|
||||||
|
# @todo we need "docker@27.5.0" in devbox.json because we need docker compose >= `v2.32.0` for `sync+exec` feature.
|
||||||
|
# For now, we don't have `sync+exec` support which means docker image rebuilds are required when updating mix.exs
|
||||||
|
# - path: ./services/bright/mix.exs
|
||||||
|
# action: sync+exec
|
||||||
|
# target: /app/mix.exs
|
||||||
|
# exec:
|
||||||
|
# command: mix deps.get
|
||||||
|
- path: ./services/bright/mix.exs
|
||||||
target: /app/mix.exs
|
target: /app/mix.exs
|
||||||
|
action: sync+restart
|
||||||
|
# - path: /home/cj/Documents/ueberauth_patreon
|
||||||
|
# action: sync
|
||||||
|
# target: /app/contrib/ueberauth_patreon
|
||||||
|
|
||||||
|
|
||||||
db:
|
db:
|
||||||
image: postgres:15
|
image: postgres:15
|
||||||
|
|
|
@ -41,12 +41,16 @@ RUN echo MIX_ENV=$MIX_ENV
|
||||||
COPY ./services/bright/mix.exs ./services/bright/mix.lock ./
|
COPY ./services/bright/mix.exs ./services/bright/mix.lock ./
|
||||||
RUN mix deps.get --only $MIX_ENV
|
RUN mix deps.get --only $MIX_ENV
|
||||||
RUN mkdir config
|
RUN mkdir config
|
||||||
|
RUN mkdir contrib
|
||||||
|
|
||||||
# copy compile-time config files before we compile dependencies
|
# copy compile-time config files before we compile dependencies
|
||||||
# to ensure any relevant config change will trigger the dependencies
|
# to ensure any relevant config change will trigger the dependencies
|
||||||
# to be re-compiled.
|
# to be re-compiled.
|
||||||
COPY ./services/bright/config/config.exs ./services/bright/config/${MIX_ENV}.exs config/
|
COPY ./services/bright/config/config.exs ./services/bright/config/${MIX_ENV}.exs config/
|
||||||
RUN ls -la config/
|
# COPY ./packages/ueberauth_patreon /app/contrib/ueberauth_patreon
|
||||||
|
# COPY ./packages/ueberauth_github /app/contrib/ueberauth_github
|
||||||
|
RUN ls -la /app/contrib/
|
||||||
|
|
||||||
RUN mix deps.compile
|
RUN mix deps.compile
|
||||||
|
|
||||||
COPY ./services/bright/priv priv
|
COPY ./services/bright/priv priv
|
||||||
|
@ -55,6 +59,7 @@ COPY ./services/bright/lib lib
|
||||||
|
|
||||||
COPY ./services/bright/assets assets
|
COPY ./services/bright/assets assets
|
||||||
|
|
||||||
|
|
||||||
# compile assets
|
# compile assets
|
||||||
RUN mix assets.deploy
|
RUN mix assets.deploy
|
||||||
|
|
||||||
|
@ -70,8 +75,8 @@ RUN mix release
|
||||||
|
|
||||||
## dev target
|
## dev target
|
||||||
FROM builder AS dev
|
FROM builder AS dev
|
||||||
# RUN mix ecto.setup
|
|
||||||
RUN echo "balls. that is all."
|
RUN echo "balls. that is all."
|
||||||
|
RUN ls -la ./contrib/
|
||||||
CMD [ "mix", "phx.server" ]
|
CMD [ "mix", "phx.server" ]
|
||||||
|
|
||||||
|
|
||||||
|
@ -94,7 +99,9 @@ WORKDIR "/app"
|
||||||
RUN chown nobody /app
|
RUN chown nobody /app
|
||||||
|
|
||||||
# set runner ENV
|
# set runner ENV
|
||||||
ENV MIX_ENV="prod"
|
ARG MIX_ENV
|
||||||
|
ENV MIX_ENV $MIX_ENV
|
||||||
|
RUN echo MIX_ENV=$MIX_ENV
|
||||||
|
|
||||||
# Only copy the final release from the build stage
|
# Only copy the final release from the build stage
|
||||||
COPY --from=builder --chown=nobody:root /app/_build/${MIX_ENV}/rel/bright ./
|
COPY --from=builder --chown=nobody:root /app/_build/${MIX_ENV}/rel/bright ./
|
||||||
|
|
|
@ -32,6 +32,16 @@ config :bright, Oban,
|
||||||
{Oban.Plugins.Lifeline, rescue_after: :timer.minutes(30)}
|
{Oban.Plugins.Lifeline, rescue_after: :timer.minutes(30)}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
# @see https://github.com/ueberauth/ueberauth
|
||||||
|
config :ueberauth, Ueberauth,
|
||||||
|
providers: [
|
||||||
|
github: {Ueberauth.Strategy.Github, [default_scope: "user:email"]},
|
||||||
|
patreon: {Ueberauth.Strategy.Patreon, []}
|
||||||
|
]
|
||||||
|
|
||||||
|
config :ueberauth, Ueberauth.Strategy.Github.OAuth,
|
||||||
|
client_id: System.get_env("GITHUB_CLIENT_ID"),
|
||||||
|
client_secret: System.get_env("GITHUB_CLIENT_SECRET")
|
||||||
|
|
||||||
# Configures the mailer
|
# Configures the mailer
|
||||||
#
|
#
|
||||||
|
|
|
@ -65,6 +65,18 @@ if config_env() == :prod do
|
||||||
],
|
],
|
||||||
secret_key_base: secret_key_base
|
secret_key_base: secret_key_base
|
||||||
|
|
||||||
|
# config :ueberauth, Ueberauth.Strategy.Patreon.OAuth,
|
||||||
|
# client_id: System.get_env("PATREON_CLIENT_ID"),
|
||||||
|
# client_secret: System.get_env("PATREON_CLIENT_SECRET")
|
||||||
|
|
||||||
|
# config :ueberauth, Ueberauth.Strategy.Github.OAuth,
|
||||||
|
# client_id: System.get_env("GITHUB_CLIENT_ID"),
|
||||||
|
# client_secret: System.get_env("GITHUB_CLIENT_SECRET")
|
||||||
|
|
||||||
|
# config :ueberauth, Ueberauth.Strategy.Github.OAuth,
|
||||||
|
# client_id: {:system, "GITHUB_CLIENT_ID"},
|
||||||
|
# client_secret: {:system, "GITHUB_CLIENT_SECRET"}
|
||||||
|
|
||||||
# ## SSL Support
|
# ## SSL Support
|
||||||
#
|
#
|
||||||
# To get SSL working, you will need to add the `https` key
|
# To get SSL working, you will need to add the `https` key
|
||||||
|
|
|
@ -10,6 +10,8 @@ defmodule Bright.Accounts do
|
||||||
|
|
||||||
## Database getters
|
## Database getters
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Gets a user by email.
|
Gets a user by email.
|
||||||
|
|
||||||
|
@ -157,6 +159,8 @@ defmodule Bright.Accounts do
|
||||||
|> Ecto.Multi.delete_all(:tokens, UserToken.by_user_and_contexts_query(user, [context]))
|
|> Ecto.Multi.delete_all(:tokens, UserToken.by_user_and_contexts_query(user, [context]))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@doc ~S"""
|
@doc ~S"""
|
||||||
Delivers the update email instructions to the given user.
|
Delivers the update email instructions to the given user.
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ defmodule Bright.Accounts.User do
|
||||||
field :hashed_password, :string, redact: true
|
field :hashed_password, :string, redact: true
|
||||||
field :current_password, :string, virtual: true, redact: true
|
field :current_password, :string, virtual: true, redact: true
|
||||||
field :confirmed_at, :utc_datetime
|
field :confirmed_at, :utc_datetime
|
||||||
|
field :provider, :string
|
||||||
|
|
||||||
timestamps(type: :utc_datetime)
|
timestamps(type: :utc_datetime)
|
||||||
end
|
end
|
||||||
|
@ -44,7 +45,7 @@ defmodule Bright.Accounts.User do
|
||||||
|
|
||||||
defp validate_email(changeset, opts) do
|
defp validate_email(changeset, opts) do
|
||||||
changeset
|
changeset
|
||||||
|> validate_required([:email])
|
|> validate_required([:email, :provider])
|
||||||
|> validate_format(:email, ~r/^[^\s]+@[^\s]+$/, message: "must have the @ sign and no spaces")
|
|> validate_format(:email, ~r/^[^\s]+@[^\s]+$/, message: "must have the @ sign and no spaces")
|
||||||
|> validate_length(:email, max: 160)
|
|> validate_length(:email, max: 160)
|
||||||
|> maybe_validate_unique_email(opts)
|
|> maybe_validate_unique_email(opts)
|
||||||
|
|
|
@ -1,12 +1,19 @@
|
||||||
defmodule Bright.User do
|
defmodule Bright.User do
|
||||||
use Ecto.Schema
|
use Ecto.Schema
|
||||||
import Ecto.Changeset
|
import Ecto.Changeset
|
||||||
|
alias Bright.Repo
|
||||||
|
|
||||||
schema "users" do
|
schema "users" do
|
||||||
field :name, :string
|
field :name, :string
|
||||||
field :email, :string
|
field :email, :string
|
||||||
field :bio, :string
|
|
||||||
field :number_of_pets, :integer
|
field :number_of_pets, :integer
|
||||||
|
field :is_admin, :boolean
|
||||||
|
field :auth_token, :string
|
||||||
|
field :auth_token_expires_at, :utc_datetime
|
||||||
|
field :signed_in_at, :utc_datetime
|
||||||
|
field :joined_at, :utc_datetime
|
||||||
|
field :patreon_handle, :string
|
||||||
|
field :github_handle, :string
|
||||||
|
|
||||||
timestamps(type: :utc_datetime)
|
timestamps(type: :utc_datetime)
|
||||||
end
|
end
|
||||||
|
@ -14,7 +21,29 @@ defmodule Bright.User do
|
||||||
@doc false
|
@doc false
|
||||||
def changeset(user, attrs) do
|
def changeset(user, attrs) do
|
||||||
user
|
user
|
||||||
|> cast(attrs, [:name, :email, :bio, :number_of_pets])
|
|> cast(attrs, [:name, :email, :bio, :number_of_pets, :is_admin])
|
||||||
|> validate_required([:name, :email, :bio, :number_of_pets])
|
|> validate_required([:name, :email, :bio, :number_of_pets])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
def get_by_ueberauth(%{provider: :github, info: %{nickname: handle}}) do
|
||||||
|
Repo.get_by(__MODULE__, github_handle: handle)
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_by_ueberauth(%{provider: :patreon, info: %{nickname: handle}}) do
|
||||||
|
Repo.get_by(__MODULE__, patreon_handle: handle)
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_by_ueberauth(_), do: nil
|
||||||
|
|
||||||
|
def sign_in_changes(user) do
|
||||||
|
change(user, %{
|
||||||
|
auth_token: nil,
|
||||||
|
auth_token_expires_at: nil,
|
||||||
|
signed_in_at: now_in_seconds(),
|
||||||
|
joined_at: user.joined_at || now_in_seconds()
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
defp now_in_seconds, do: Timex.now() |> DateTime.truncate(:second)
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,70 @@
|
||||||
|
defmodule Bright.UserFromAuth do
|
||||||
|
@moduledoc """
|
||||||
|
Retrieve the user information from an auth request
|
||||||
|
"""
|
||||||
|
require Logger
|
||||||
|
require Jason
|
||||||
|
|
||||||
|
alias Ueberauth.Auth
|
||||||
|
|
||||||
|
def find_or_create(%Auth{provider: :identity} = auth) do
|
||||||
|
case validate_pass(auth.credentials) do
|
||||||
|
:ok ->
|
||||||
|
{:ok, basic_info(auth)}
|
||||||
|
|
||||||
|
{:error, reason} ->
|
||||||
|
{:error, reason}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def find_or_create(%Auth{} = auth) do
|
||||||
|
{:ok, basic_info(auth)}
|
||||||
|
end
|
||||||
|
|
||||||
|
# github does it this way
|
||||||
|
defp avatar_from_auth(%{info: %{urls: %{avatar_url: image}}}), do: image
|
||||||
|
|
||||||
|
# facebook does it this way
|
||||||
|
defp avatar_from_auth(%{info: %{image: image}}), do: image
|
||||||
|
|
||||||
|
# default case if nothing matches
|
||||||
|
defp avatar_from_auth(auth) do
|
||||||
|
Logger.warn("#{auth.provider} needs to find an avatar URL!")
|
||||||
|
Logger.debug(Jason.encode!(auth))
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
|
||||||
|
defp basic_info(auth) do
|
||||||
|
%{id: auth.uid, name: name_from_auth(auth), avatar: avatar_from_auth(auth)}
|
||||||
|
end
|
||||||
|
|
||||||
|
defp name_from_auth(auth) do
|
||||||
|
if auth.info.name do
|
||||||
|
auth.info.name
|
||||||
|
else
|
||||||
|
name =
|
||||||
|
[auth.info.first_name, auth.info.last_name]
|
||||||
|
|> Enum.filter(&(&1 != nil and &1 != ""))
|
||||||
|
|
||||||
|
if Enum.empty?(name) do
|
||||||
|
auth.info.nickname
|
||||||
|
else
|
||||||
|
Enum.join(name, " ")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp validate_pass(%{other: %{password: nil}}) do
|
||||||
|
{:error, "Password required"}
|
||||||
|
end
|
||||||
|
|
||||||
|
defp validate_pass(%{other: %{password: pw, password_confirmation: pw}}) do
|
||||||
|
:ok
|
||||||
|
end
|
||||||
|
|
||||||
|
defp validate_pass(%{other: %{password: _}}) do
|
||||||
|
{:error, "Passwords do not match"}
|
||||||
|
end
|
||||||
|
|
||||||
|
defp validate_pass(_), do: {:error, "Password Required"}
|
||||||
|
end
|
|
@ -21,7 +21,7 @@ defmodule BrightWeb do
|
||||||
|
|
||||||
def router do
|
def router do
|
||||||
quote do
|
quote do
|
||||||
use Phoenix.Router, helpers: false
|
use Phoenix.Router, helpers: true
|
||||||
|
|
||||||
# Import common connection and controller functions to use in pipelines
|
# Import common connection and controller functions to use in pipelines
|
||||||
import Plug.Conn
|
import Plug.Conn
|
||||||
|
|
|
@ -112,7 +112,6 @@ defmodule BrightWeb.CoreComponents do
|
||||||
<div
|
<div
|
||||||
:if={msg = render_slot(@inner_block) || Phoenix.Flash.get(@flash, @kind)}
|
:if={msg = render_slot(@inner_block) || Phoenix.Flash.get(@flash, @kind)}
|
||||||
id={@id}
|
id={@id}
|
||||||
phx-click={JS.push("lv:clear-flash", value: %{key: @kind}) |> hide("##{@id}")}
|
|
||||||
role="alert"
|
role="alert"
|
||||||
class={[
|
class={[
|
||||||
"mb-5 notification",
|
"mb-5 notification",
|
||||||
|
@ -121,7 +120,12 @@ defmodule BrightWeb.CoreComponents do
|
||||||
]}
|
]}
|
||||||
{@rest}
|
{@rest}
|
||||||
>
|
>
|
||||||
<button type="button" class="delete" aria-label={gettext("close")}></button>
|
<button
|
||||||
|
type="button"
|
||||||
|
class="delete"
|
||||||
|
aria-label={gettext("close")}
|
||||||
|
phx-click={JS.push("lv:clear-flash", value: %{key: @kind}) |> hide("##{@id}")}
|
||||||
|
></button>
|
||||||
<p :if={@title} class="has-text-weight-bold">
|
<p :if={@title} class="has-text-weight-bold">
|
||||||
<%= @title %>
|
<%= @title %>
|
||||||
</p>
|
</p>
|
||||||
|
|
|
@ -97,7 +97,7 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- <%= if @current_user do %>
|
<%= if @current_user do %>
|
||||||
<.link
|
<.link
|
||||||
href={~p"/profile"}
|
href={~p"/profile"}
|
||||||
class="navbar-item">
|
class="navbar-item">
|
||||||
|
@ -123,13 +123,19 @@
|
||||||
>
|
>
|
||||||
Register
|
Register
|
||||||
</.link>
|
</.link>
|
||||||
<.link
|
<%# <.link
|
||||||
href={~p"/users/log_in"}
|
href={~p"/auth/github"}
|
||||||
class="navbar-item"
|
class="navbar-item"
|
||||||
>
|
>
|
||||||
Log in
|
Log in
|
||||||
</.link>
|
</.link>
|
||||||
<% end %> -->
|
<.link
|
||||||
|
href={~p"/auth/github"}
|
||||||
|
class="navbar-item"
|
||||||
|
>
|
||||||
|
Log in via GH
|
||||||
|
</.link> %>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -0,0 +1,92 @@
|
||||||
|
|
||||||
|
|
||||||
|
defmodule BrightWeb.AuthController do
|
||||||
|
@moduledoc """
|
||||||
|
Auth controller responsible for handling Ueberauth responses
|
||||||
|
"""
|
||||||
|
|
||||||
|
require Logger
|
||||||
|
use BrightWeb, :controller
|
||||||
|
|
||||||
|
plug Ueberauth
|
||||||
|
|
||||||
|
alias Ueberauth.Strategy.Helpers
|
||||||
|
alias Bright.UserFromAuth
|
||||||
|
alias Bright.User
|
||||||
|
|
||||||
|
|
||||||
|
def delete(conn, _params) do
|
||||||
|
conn
|
||||||
|
|> put_flash(:info, "You have been logged out!")
|
||||||
|
|> clear_session()
|
||||||
|
|> redirect(to: "/")
|
||||||
|
end
|
||||||
|
|
||||||
|
def callback(%{assigns: %{ueberauth_failure: _fails}} = conn, _params) do
|
||||||
|
conn
|
||||||
|
|> put_flash(:error, "Failed to authenticate.")
|
||||||
|
|> redirect(to: "/")
|
||||||
|
end
|
||||||
|
|
||||||
|
# def callback(conn, %{"provider" => provider}) do
|
||||||
|
# end
|
||||||
|
|
||||||
|
def callback(conn = %{assigns: %{ueberauth_auth: auth}}, _params) do
|
||||||
|
if user = User.get_by_ueberauth(auth) do
|
||||||
|
sign_in_and_redirect(conn, user, ~p"/~")
|
||||||
|
else
|
||||||
|
conn
|
||||||
|
|> put_flash(:success, "Almost there! Please complete your profile now.")
|
||||||
|
|> redirect(to: ~p"/join?#{params_from_ueberauth(auth)}")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
defp sign_in_and_redirect(conn, user, route) do
|
||||||
|
user
|
||||||
|
|> User.sign_in_changes()
|
||||||
|
|> Repo.update()
|
||||||
|
|
||||||
|
conn
|
||||||
|
|> assign(:current_user, user)
|
||||||
|
|> put_flash(:success, "Welcome!")
|
||||||
|
|> put_session("id", user.id)
|
||||||
|
|> configure_session(renew: true)
|
||||||
|
|> redirect(to: route)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
defp params_from_ueberauth(%{provider: :github, info: info}) do
|
||||||
|
%{name: info.name, handle: info.nickname, github_handle: info.nickname}
|
||||||
|
end
|
||||||
|
|
||||||
|
defp params_from_ueberauth(%{provider: :patreon, info: info}) do
|
||||||
|
%{name: info.name, handle: info.nickname, patreon_handle: info.nickname}
|
||||||
|
end
|
||||||
|
|
||||||
|
# case Ueberauth.Auth.fetch!(conn) do
|
||||||
|
# {:ok, auth} ->
|
||||||
|
# Logger.info("auth is as follows: #{inspect(auth)}")
|
||||||
|
# {:error, reason} ->
|
||||||
|
# conn
|
||||||
|
# |> put_flash(:error, "Auth failed! #{reason}")
|
||||||
|
# |> redirect(to: ~p"/")
|
||||||
|
# end
|
||||||
|
|
||||||
|
# case UserFromAuth.find_or_create(auth) do
|
||||||
|
# {:ok, user} ->
|
||||||
|
# conn
|
||||||
|
# |> put_flash(:info, "Successfully authenticated #{inspect(user)}")
|
||||||
|
# |> put_session(:current_user, user)
|
||||||
|
# |> configure_session(renew: true)
|
||||||
|
# |> redirect(to: "/")
|
||||||
|
|
||||||
|
# {:error, reason} ->
|
||||||
|
# conn
|
||||||
|
# |> put_flash(:error, reason)
|
||||||
|
# |> redirect(to: "/")
|
||||||
|
# end
|
||||||
|
|
||||||
|
end
|
|
@ -0,0 +1,7 @@
|
||||||
|
defmodule BrightWeb.AuthHTML do
|
||||||
|
use BrightWeb, :html
|
||||||
|
|
||||||
|
|
||||||
|
embed_templates "auth_html/*"
|
||||||
|
|
||||||
|
end
|
|
@ -0,0 +1 @@
|
||||||
|
<p>hello this is request.html</p>
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<p class="title is-2">
|
<p class="title is-2">
|
||||||
The Galaxy's Best VTuber Hentai Site
|
The Galaxy's Best VTuber Hentai Site
|
||||||
</p>
|
</p>
|
||||||
|
@ -25,6 +26,20 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<!--<%= inspect(@current_user) %>
|
||||||
|
<%= if @current_user do %>
|
||||||
|
<div>
|
||||||
|
<h1>Welcome, <%= @current_user[:name] %>!</h1>
|
||||||
|
<p>ID: <%= @current_user[:id] %></p>
|
||||||
|
<p>Avatar: <%= @current_user[:avatar] %></p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<% else %>
|
||||||
|
<div>
|
||||||
|
<p>You are not logged in. Please <a href="/auth/github">log in</a>.</p>
|
||||||
|
</div>
|
||||||
|
<% end %>-->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
defmodule BrightWeb.UserController do
|
||||||
|
use BrightWeb, :controller
|
||||||
|
|
||||||
|
def index(conn, _params) do
|
||||||
|
render(conn, :index)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
def show(conn) do
|
||||||
|
conn
|
||||||
|
|> render(:show)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
end
|
|
@ -0,0 +1,4 @@
|
||||||
|
defmodule BrightWeb.UserHTML do
|
||||||
|
use BrightWeb, :html
|
||||||
|
embed_templates "user_html/*"
|
||||||
|
end
|
|
@ -0,0 +1,11 @@
|
||||||
|
|
||||||
|
<.header>
|
||||||
|
Visitor Profile
|
||||||
|
</.header>
|
||||||
|
|
||||||
|
<%= if @current_user do %>
|
||||||
|
<p>@current_user is {@current_user}</p>
|
||||||
|
<% else %>
|
||||||
|
<p>there is no @current_user</p>
|
||||||
|
<% end %>
|
||||||
|
|
|
@ -24,16 +24,27 @@ defmodule BrightWeb.Router do
|
||||||
plug :accepts, ["json"]
|
plug :accepts, ["json"]
|
||||||
end
|
end
|
||||||
|
|
||||||
# scope "/" do
|
|
||||||
# pipe_through [:browser, :require_authenticated_user, :require_admin_user]
|
|
||||||
# ## !!! DANGER, platforms must only be writable by admins, (unless we implement SVG sanitizing)
|
|
||||||
# get "/platforms/new", PlatformController, :new
|
|
||||||
# post "/platforms", PlatformController, :create
|
|
||||||
# get "/platforms/:id/edit", PlatformController, :edit
|
|
||||||
# patch "/platforms/:id", PlatformController, :update
|
|
||||||
# put "/platforms/:id", PlatformController, :update
|
|
||||||
|
|
||||||
# end
|
|
||||||
|
scope "/" do
|
||||||
|
pipe_through [:browser, :require_authenticated_user, :require_admin_user]
|
||||||
|
## !!! DANGER, platforms must only be writable by admins, (unless we implement SVG sanitizing)
|
||||||
|
get "/platforms/new", PlatformController, :new
|
||||||
|
post "/platforms", PlatformController, :create
|
||||||
|
get "/platforms/:id/edit", PlatformController, :edit
|
||||||
|
patch "/platforms/:id", PlatformController, :update
|
||||||
|
put "/platforms/:id", PlatformController, :update
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
scope "/auth", BrightWeb do
|
||||||
|
pipe_through :browser
|
||||||
|
|
||||||
|
get "/:provider", AuthController, :request
|
||||||
|
get "/:provider/callback", AuthController, :callback
|
||||||
|
post "/:provider/callback", AuthController, :callback
|
||||||
|
delete "/logout", AuthController, :delete
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
scope "/" do
|
scope "/" do
|
||||||
|
@ -58,6 +69,8 @@ defmodule BrightWeb.Router do
|
||||||
# get "/vtubers/:id/edit", VtuberController, :edit
|
# get "/vtubers/:id/edit", VtuberController, :edit
|
||||||
# end
|
# end
|
||||||
|
|
||||||
|
get "/profile", UserController, :show
|
||||||
|
|
||||||
|
|
||||||
get "/tags/new", TagController, :new
|
get "/tags/new", TagController, :new
|
||||||
post "/tags", TagController, :create
|
post "/tags", TagController, :create
|
||||||
|
@ -82,8 +95,6 @@ defmodule BrightWeb.Router do
|
||||||
get "/streams", StreamController, :index
|
get "/streams", StreamController, :index
|
||||||
get "/streams/:id", StreamController, :show
|
get "/streams/:id", StreamController, :show
|
||||||
|
|
||||||
# get "/vods", VodController, :index
|
|
||||||
# get "/vods/:id", VodController, :show
|
|
||||||
|
|
||||||
resources "/vods", VodController
|
resources "/vods", VodController
|
||||||
get "/vods/:id", VodController, :show
|
get "/vods/:id", VodController, :show
|
||||||
|
|
|
@ -5,6 +5,7 @@ defmodule BrightWeb.UserAuth do
|
||||||
import Phoenix.Controller
|
import Phoenix.Controller
|
||||||
|
|
||||||
alias Bright.Accounts
|
alias Bright.Accounts
|
||||||
|
alias Bright.User
|
||||||
|
|
||||||
# Make the remember me cookie valid for 60 days.
|
# Make the remember me cookie valid for 60 days.
|
||||||
# If you want bump or reduce this value, also change
|
# If you want bump or reduce this value, also change
|
||||||
|
@ -208,11 +209,37 @@ defmodule BrightWeb.UserAuth do
|
||||||
conn
|
conn
|
||||||
|> put_flash(:error, "You must log in to access this page.")
|
|> put_flash(:error, "You must log in to access this page.")
|
||||||
|> maybe_store_return_to()
|
|> maybe_store_return_to()
|
||||||
|> redirect(to: ~p"/users/log_in")
|
|> redirect(to: ~p"/auth/github")
|
||||||
|> halt()
|
|> halt()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Used for routes that require the user to be an administrator.
|
||||||
|
"""
|
||||||
|
def require_admin_user(conn, _opts) do
|
||||||
|
Logger.info("con.assigns[:current_user] as follows. #{inspect(conn.assigns)}")
|
||||||
|
|
||||||
|
case conn.assigns[:current_user] do
|
||||||
|
%User{is_admin: true} -> # Assuming the user struct has an `is_admin` field
|
||||||
|
conn
|
||||||
|
|
||||||
|
%User{} ->
|
||||||
|
conn
|
||||||
|
|> put_flash(:error, "You do not have permission to access this page.")
|
||||||
|
|> redirect(to: ~p"/")
|
||||||
|
|> halt()
|
||||||
|
|
||||||
|
nil ->
|
||||||
|
conn
|
||||||
|
|> put_flash(:error, "You must log in to access this page.")
|
||||||
|
|> maybe_store_return_to()
|
||||||
|
|> redirect(to: ~p"/auth/github")
|
||||||
|
|> halt()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
defp put_token_in_session(conn, token) do
|
defp put_token_in_session(conn, token) do
|
||||||
conn
|
conn
|
||||||
|> put_session(:user_token, token)
|
|> put_session(:user_token, token)
|
||||||
|
|
|
@ -56,7 +56,10 @@ defmodule Bright.MixProject do
|
||||||
{:bandit, "~> 1.5"},
|
{:bandit, "~> 1.5"},
|
||||||
{:oban, "~> 2.17"},
|
{:oban, "~> 2.17"},
|
||||||
{:mox, "~> 0.5.0", only: :test},
|
{:mox, "~> 0.5.0", only: :test},
|
||||||
{:httpoison, "~> 2.0"}
|
{:httpoison, "~> 2.0"},
|
||||||
|
{:ueberauth, "~> 0.7.0"},
|
||||||
|
{:ueberauth_github, "~> 0.8"},
|
||||||
|
{:timex, "~> 3.0"},
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
"bulma": {:hex, :bulma, "1.0.2", "50dfffe8d28b0bd527418560223b407f9e80e990e187e1653b17eff818f8fcbe", [:mix], [], "hexpm", "27745727ff7f451d140a2438c0ca4448bc8ca73e0a6d2d4f24e1b5b9ced8a774"},
|
"bulma": {:hex, :bulma, "1.0.2", "50dfffe8d28b0bd527418560223b407f9e80e990e187e1653b17eff818f8fcbe", [:mix], [], "hexpm", "27745727ff7f451d140a2438c0ca4448bc8ca73e0a6d2d4f24e1b5b9ced8a774"},
|
||||||
"castore": {:hex, :castore, "1.0.10", "43bbeeac820f16c89f79721af1b3e092399b3a1ecc8df1a472738fd853574911", [:mix], [], "hexpm", "1b0b7ea14d889d9ea21202c43a4fa015eb913021cb535e8ed91946f4b77a8848"},
|
"castore": {:hex, :castore, "1.0.10", "43bbeeac820f16c89f79721af1b3e092399b3a1ecc8df1a472738fd853574911", [:mix], [], "hexpm", "1b0b7ea14d889d9ea21202c43a4fa015eb913021cb535e8ed91946f4b77a8848"},
|
||||||
"certifi": {:hex, :certifi, "2.12.0", "2d1cca2ec95f59643862af91f001478c9863c2ac9cb6e2f89780bfd8de987329", [:rebar3], [], "hexpm", "ee68d85df22e554040cdb4be100f33873ac6051387baf6a8f6ce82272340ff1c"},
|
"certifi": {:hex, :certifi, "2.12.0", "2d1cca2ec95f59643862af91f001478c9863c2ac9cb6e2f89780bfd8de987329", [:rebar3], [], "hexpm", "ee68d85df22e554040cdb4be100f33873ac6051387baf6a8f6ce82272340ff1c"},
|
||||||
|
"combine": {:hex, :combine, "0.10.0", "eff8224eeb56498a2af13011d142c5e7997a80c8f5b97c499f84c841032e429f", [:mix], [], "hexpm", "1b1dbc1790073076580d0d1d64e42eae2366583e7aecd455d1215b0d16f2451b"},
|
||||||
"comeonin": {:hex, :comeonin, "5.5.0", "364d00df52545c44a139bad919d7eacb55abf39e86565878e17cebb787977368", [:mix], [], "hexpm", "6287fc3ba0aad34883cbe3f7949fc1d1e738e5ccdce77165bc99490aa69f47fb"},
|
"comeonin": {:hex, :comeonin, "5.5.0", "364d00df52545c44a139bad919d7eacb55abf39e86565878e17cebb787977368", [:mix], [], "hexpm", "6287fc3ba0aad34883cbe3f7949fc1d1e738e5ccdce77165bc99490aa69f47fb"},
|
||||||
"dart_sass": {:hex, :dart_sass, "0.7.0", "7979e056cb74fd6843e1c72db763cffc7726a9192a657735b7d24c0d9c26a1ce", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}], "hexpm", "4a8e70bca41aa00846398abdf5ad8a64d7907a0f7bf40145cd2e40d5971629f2"},
|
"dart_sass": {:hex, :dart_sass, "0.7.0", "7979e056cb74fd6843e1c72db763cffc7726a9192a657735b7d24c0d9c26a1ce", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}], "hexpm", "4a8e70bca41aa00846398abdf5ad8a64d7907a0f7bf40145cd2e40d5971629f2"},
|
||||||
"db_connection": {:hex, :db_connection, "2.7.0", "b99faa9291bb09892c7da373bb82cba59aefa9b36300f6145c5f201c7adf48ec", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "dcf08f31b2701f857dfc787fbad78223d61a32204f217f15e881dd93e4bdd3ff"},
|
"db_connection": {:hex, :db_connection, "2.7.0", "b99faa9291bb09892c7da373bb82cba59aefa9b36300f6145c5f201c7adf48ec", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "dcf08f31b2701f857dfc787fbad78223d61a32204f217f15e881dd93e4bdd3ff"},
|
||||||
|
@ -31,6 +32,7 @@
|
||||||
"mox": {:hex, :mox, "0.5.2", "55a0a5ba9ccc671518d068c8dddd20eeb436909ea79d1799e2209df7eaa98b6c", [:mix], [], "hexpm", "df4310628cd628ee181df93f50ddfd07be3e5ecc30232d3b6aadf30bdfe6092b"},
|
"mox": {:hex, :mox, "0.5.2", "55a0a5ba9ccc671518d068c8dddd20eeb436909ea79d1799e2209df7eaa98b6c", [:mix], [], "hexpm", "df4310628cd628ee181df93f50ddfd07be3e5ecc30232d3b6aadf30bdfe6092b"},
|
||||||
"nimble_options": {:hex, :nimble_options, "1.1.1", "e3a492d54d85fc3fd7c5baf411d9d2852922f66e69476317787a7b2bb000a61b", [:mix], [], "hexpm", "821b2470ca9442c4b6984882fe9bb0389371b8ddec4d45a9504f00a66f650b44"},
|
"nimble_options": {:hex, :nimble_options, "1.1.1", "e3a492d54d85fc3fd7c5baf411d9d2852922f66e69476317787a7b2bb000a61b", [:mix], [], "hexpm", "821b2470ca9442c4b6984882fe9bb0389371b8ddec4d45a9504f00a66f650b44"},
|
||||||
"nimble_pool": {:hex, :nimble_pool, "1.1.0", "bf9c29fbdcba3564a8b800d1eeb5a3c58f36e1e11d7b7fb2e084a643f645f06b", [:mix], [], "hexpm", "af2e4e6b34197db81f7aad230c1118eac993acc0dae6bc83bac0126d4ae0813a"},
|
"nimble_pool": {:hex, :nimble_pool, "1.1.0", "bf9c29fbdcba3564a8b800d1eeb5a3c58f36e1e11d7b7fb2e084a643f645f06b", [:mix], [], "hexpm", "af2e4e6b34197db81f7aad230c1118eac993acc0dae6bc83bac0126d4ae0813a"},
|
||||||
|
"oauth2": {:hex, :oauth2, "2.1.0", "beb657f393814a3a7a8a15bd5e5776ecae341fd344df425342a3b6f1904c2989", [:mix], [{:tesla, "~> 1.5", [hex: :tesla, repo: "hexpm", optional: false]}], "hexpm", "8ac07f85b3307dd1acfeb0ec852f64161b22f57d0ce0c15e616a1dfc8ebe2b41"},
|
||||||
"oban": {:hex, :oban, "2.18.3", "1608c04f8856c108555c379f2f56bc0759149d35fa9d3b825cb8a6769f8ae926", [:mix], [{:ecto_sql, "~> 3.10", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:ecto_sqlite3, "~> 0.9", [hex: :ecto_sqlite3, repo: "hexpm", optional: true]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.16", [hex: :postgrex, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "36ca6ca84ef6518f9c2c759ea88efd438a3c81d667ba23b02b062a0aa785475e"},
|
"oban": {:hex, :oban, "2.18.3", "1608c04f8856c108555c379f2f56bc0759149d35fa9d3b825cb8a6769f8ae926", [:mix], [{:ecto_sql, "~> 3.10", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:ecto_sqlite3, "~> 0.9", [hex: :ecto_sqlite3, repo: "hexpm", optional: true]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.16", [hex: :postgrex, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "36ca6ca84ef6518f9c2c759ea88efd438a3c81d667ba23b02b062a0aa785475e"},
|
||||||
"parse_trans": {:hex, :parse_trans, "3.4.1", "6e6aa8167cb44cc8f39441d05193be6e6f4e7c2946cb2759f015f8c56b76e5ff", [:rebar3], [], "hexpm", "620a406ce75dada827b82e453c19cf06776be266f5a67cff34e1ef2cbb60e49a"},
|
"parse_trans": {:hex, :parse_trans, "3.4.1", "6e6aa8167cb44cc8f39441d05193be6e6f4e7c2946cb2759f015f8c56b76e5ff", [:rebar3], [], "hexpm", "620a406ce75dada827b82e453c19cf06776be266f5a67cff34e1ef2cbb60e49a"},
|
||||||
"phoenix": {:hex, :phoenix, "1.7.18", "5310c21443514be44ed93c422e15870aef254cf1b3619e4f91538e7529d2b2e4", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.1", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: true]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.7", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:websock_adapter, "~> 0.5.3", [hex: :websock_adapter, repo: "hexpm", optional: false]}], "hexpm", "1797fcc82108442a66f2c77a643a62980f342bfeb63d6c9a515ab8294870004e"},
|
"phoenix": {:hex, :phoenix, "1.7.18", "5310c21443514be44ed93c422e15870aef254cf1b3619e4f91538e7529d2b2e4", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.1", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: true]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.7", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:websock_adapter, "~> 0.5.3", [hex: :websock_adapter, repo: "hexpm", optional: false]}], "hexpm", "1797fcc82108442a66f2c77a643a62980f342bfeb63d6c9a515ab8294870004e"},
|
||||||
|
@ -52,7 +54,12 @@
|
||||||
"telemetry": {:hex, :telemetry, "1.3.0", "fedebbae410d715cf8e7062c96a1ef32ec22e764197f70cda73d82778d61e7a2", [:rebar3], [], "hexpm", "7015fc8919dbe63764f4b4b87a95b7c0996bd539e0d499be6ec9d7f3875b79e6"},
|
"telemetry": {:hex, :telemetry, "1.3.0", "fedebbae410d715cf8e7062c96a1ef32ec22e764197f70cda73d82778d61e7a2", [:rebar3], [], "hexpm", "7015fc8919dbe63764f4b4b87a95b7c0996bd539e0d499be6ec9d7f3875b79e6"},
|
||||||
"telemetry_metrics": {:hex, :telemetry_metrics, "1.0.0", "29f5f84991ca98b8eb02fc208b2e6de7c95f8bb2294ef244a176675adc7775df", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "f23713b3847286a534e005126d4c959ebcca68ae9582118ce436b521d1d47d5d"},
|
"telemetry_metrics": {:hex, :telemetry_metrics, "1.0.0", "29f5f84991ca98b8eb02fc208b2e6de7c95f8bb2294ef244a176675adc7775df", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "f23713b3847286a534e005126d4c959ebcca68ae9582118ce436b521d1d47d5d"},
|
||||||
"telemetry_poller": {:hex, :telemetry_poller, "1.1.0", "58fa7c216257291caaf8d05678c8d01bd45f4bdbc1286838a28c4bb62ef32999", [:rebar3], [{:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "9eb9d9cbfd81cbd7cdd24682f8711b6e2b691289a0de6826e58452f28c103c8f"},
|
"telemetry_poller": {:hex, :telemetry_poller, "1.1.0", "58fa7c216257291caaf8d05678c8d01bd45f4bdbc1286838a28c4bb62ef32999", [:rebar3], [{:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "9eb9d9cbfd81cbd7cdd24682f8711b6e2b691289a0de6826e58452f28c103c8f"},
|
||||||
|
"tesla": {:hex, :tesla, "1.12.3", "7189f71ac607169a1bb2dfcf8747dedd4d9384ec00cec6c7b38c5f03811a73c7", [:mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:exjsx, ">= 3.0.0", [hex: :exjsx, repo: "hexpm", optional: true]}, {:finch, "~> 0.13", [hex: :finch, repo: "hexpm", optional: true]}, {:fuse, "~> 2.4", [hex: :fuse, repo: "hexpm", optional: true]}, {:gun, ">= 1.0.0", [hex: :gun, repo: "hexpm", optional: true]}, {:hackney, "~> 1.6", [hex: :hackney, repo: "hexpm", optional: true]}, {:ibrowse, "4.4.2", [hex: :ibrowse, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: true]}, {:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.0", [hex: :mint, repo: "hexpm", optional: true]}, {:msgpax, "~> 2.3", [hex: :msgpax, repo: "hexpm", optional: true]}, {:poison, ">= 1.0.0", [hex: :poison, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "4dfb0d6a81ca79c8662a4f03884843a5b3251825ba47ea6f9ab84dcc354fdeec"},
|
||||||
"thousand_island": {:hex, :thousand_island, "1.3.7", "1da7598c0f4f5f50562c097a3f8af308ded48cd35139f0e6f17d9443e4d0c9c5", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "0139335079953de41d381a6134d8b618d53d084f558c734f2662d1a72818dd12"},
|
"thousand_island": {:hex, :thousand_island, "1.3.7", "1da7598c0f4f5f50562c097a3f8af308ded48cd35139f0e6f17d9443e4d0c9c5", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "0139335079953de41d381a6134d8b618d53d084f558c734f2662d1a72818dd12"},
|
||||||
|
"timex": {:hex, :timex, "3.7.11", "bb95cb4eb1d06e27346325de506bcc6c30f9c6dea40d1ebe390b262fad1862d1", [:mix], [{:combine, "~> 0.10", [hex: :combine, repo: "hexpm", optional: false]}, {:gettext, "~> 0.20", [hex: :gettext, repo: "hexpm", optional: false]}, {:tzdata, "~> 1.1", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm", "8b9024f7efbabaf9bd7aa04f65cf8dcd7c9818ca5737677c7b76acbc6a94d1aa"},
|
||||||
|
"tzdata": {:hex, :tzdata, "1.1.2", "45e5f1fcf8729525ec27c65e163be5b3d247ab1702581a94674e008413eef50b", [:mix], [{:hackney, "~> 1.17", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "cec7b286e608371602318c414f344941d5eb0375e14cfdab605cca2fe66cba8b"},
|
||||||
|
"ueberauth": {:hex, :ueberauth, "0.7.0", "9c44f41798b5fa27f872561b6f7d2bb0f10f03fdd22b90f454232d7b087f4b75", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "2efad9022e949834f16cc52cd935165049d81fa9e925690f91035c2e4b58d905"},
|
||||||
|
"ueberauth_github": {:hex, :ueberauth_github, "0.8.3", "1c478629b4c1dae446c68834b69194ad5cead3b6c67c913db6fdf64f37f0328f", [:mix], [{:oauth2, "~> 1.0 or ~> 2.0", [hex: :oauth2, repo: "hexpm", optional: false]}, {:ueberauth, "~> 0.7", [hex: :ueberauth, repo: "hexpm", optional: false]}], "hexpm", "ae0ab2879c32cfa51d7287a48219b262bfdab0b7ec6629f24160564247493cc6"},
|
||||||
"unicode_util_compat": {:hex, :unicode_util_compat, "0.7.0", "bc84380c9ab48177092f43ac89e4dfa2c6d62b40b8bd132b1059ecc7232f9a78", [:rebar3], [], "hexpm", "25eee6d67df61960cf6a794239566599b09e17e668d3700247bc498638152521"},
|
"unicode_util_compat": {:hex, :unicode_util_compat, "0.7.0", "bc84380c9ab48177092f43ac89e4dfa2c6d62b40b8bd132b1059ecc7232f9a78", [:rebar3], [], "hexpm", "25eee6d67df61960cf6a794239566599b09e17e668d3700247bc498638152521"},
|
||||||
"websock": {:hex, :websock, "0.5.3", "2f69a6ebe810328555b6fe5c831a851f485e303a7c8ce6c5f675abeb20ebdadc", [:mix], [], "hexpm", "6105453d7fac22c712ad66fab1d45abdf049868f253cf719b625151460b8b453"},
|
"websock": {:hex, :websock, "0.5.3", "2f69a6ebe810328555b6fe5c831a851f485e303a7c8ce6c5f675abeb20ebdadc", [:mix], [], "hexpm", "6105453d7fac22c712ad66fab1d45abdf049868f253cf719b625151460b8b453"},
|
||||||
"websock_adapter": {:hex, :websock_adapter, "0.5.8", "3b97dc94e407e2d1fc666b2fb9acf6be81a1798a2602294aac000260a7c4a47d", [:mix], [{:bandit, ">= 0.6.0", [hex: :bandit, repo: "hexpm", optional: true]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.6", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:websock, "~> 0.5", [hex: :websock, repo: "hexpm", optional: false]}], "hexpm", "315b9a1865552212b5f35140ad194e67ce31af45bcee443d4ecb96b5fd3f3782"},
|
"websock_adapter": {:hex, :websock_adapter, "0.5.8", "3b97dc94e407e2d1fc666b2fb9acf6be81a1798a2602294aac000260a7c4a47d", [:mix], [{:bandit, ">= 0.6.0", [hex: :bandit, repo: "hexpm", optional: true]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.6", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:websock, "~> 0.5", [hex: :websock, repo: "hexpm", optional: false]}], "hexpm", "315b9a1865552212b5f35140ad194e67ce31af45bcee443d4ecb96b5fd3f3782"},
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
defmodule Bright.Repo.Migrations.AddPlatformToUser do
|
||||||
|
use Ecto.Migration
|
||||||
|
|
||||||
|
def change do
|
||||||
|
alter table(:users) do
|
||||||
|
add :is_admin, :boolean, default: false, null: false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,9 @@
|
||||||
|
defmodule Bright.Repo.Migrations.AddIsAdminToUser do
|
||||||
|
use Ecto.Migration
|
||||||
|
|
||||||
|
def change do
|
||||||
|
alter table(:users) do
|
||||||
|
add :is_admin, :boolean, default: false, null: false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,12 @@
|
||||||
|
defmodule Bright.Repo.Migrations.AddAuthTokenToUser do
|
||||||
|
use Ecto.Migration
|
||||||
|
|
||||||
|
def change do
|
||||||
|
alter table(:users) do
|
||||||
|
add :auth_token, :string
|
||||||
|
add :auth_token_expires_at, :utc_datetime
|
||||||
|
add :joined_at, :utc_datetime
|
||||||
|
add :signed_in_at, :utc_datetime
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,10 @@
|
||||||
|
defmodule Bright.Repo.Migrations.AddProviderHandlesToUser do
|
||||||
|
use Ecto.Migration
|
||||||
|
|
||||||
|
def change do
|
||||||
|
alter table(:users) do
|
||||||
|
add :patreon_handle, :string
|
||||||
|
add :github_handle, :string
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,9 @@
|
||||||
|
defmodule Bright.Repo.Migrations.AddNameToUser do
|
||||||
|
use Ecto.Migration
|
||||||
|
|
||||||
|
def change do
|
||||||
|
alter table(:users) do
|
||||||
|
add :name, :string
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in New Issue