basic website complete

- ported posts from Efiens
- add CV
- add MachO obfuscation whitepaper
This commit is contained in:
2023-10-25 01:12:36 +07:00
parent 7a8ce17237
commit 7968743f3c
16 changed files with 1785 additions and 45 deletions

98
app/Route/Blog.elm Normal file
View File

@ -0,0 +1,98 @@
module Route.Blog exposing (ActionData, Data, Model, Msg, route)
import Article
import BackendTask exposing (BackendTask)
import Date exposing (Date)
import FatalError exposing (FatalError)
import Head
import Head.Seo as Seo
import Html.Styled exposing (..)
import Json.Decode as Decode exposing (Decoder)
import Json.Decode.Extra
import Pages.Url
import PagesMsg exposing (PagesMsg)
import Route exposing (Route)
import RouteBuilder exposing (App, StatelessRoute)
import Shared
import View exposing (View)
import Link
import Markdown.Block
import Markdown.Renderer
import MarkdownCodec
import TailwindMarkdownRenderer
import Tailwind.Utilities as Tw
type alias Model =
{}
type alias Msg =
()
type alias RouteParams =
{}
route : StatelessRoute RouteParams Data ActionData
route =
RouteBuilder.single
{ head = head
, data = data
}
|> RouteBuilder.buildNoState { view = view }
type alias Data =
List (Route, Article.ArticleMetadata)
type alias ActionData =
{}
data : BackendTask FatalError Data
data =
Article.blogAllMetadata
|> BackendTask.allowFatal
head :
App Data ActionData RouteParams
-> List Head.Tag
head app =
Seo.summary
{ canonicalUrlOverride = Nothing
, siteName = "elm-pages"
, image =
{ url = Pages.Url.external "TODO"
, alt = "elm-pages logo"
, dimensions = Nothing
, mimeType = Nothing
}
, description = "TODO"
, locale = Nothing
, title = "TODO title" -- metadata.title -- TODO
}
|> Seo.website
view :
App Data ActionData RouteParams
-> Shared.Model
-> View msg
view app shared =
{ title = "title"
, body = app.data
|> List.map renderBlogItem
}
renderBlogItem : (Route, Article.ArticleMetadata) -> Html msg
renderBlogItem (route_, article) =
Link.link (Link.internal route_) []
[ div []
[ div []
[ text article.title
, text article.summary
]
]
]

View File

@ -86,7 +86,7 @@ frontmatterDecoder : Decoder ArticleMetadata
frontmatterDecoder =
Decode.map4 ArticleMetadata
(Decode.field "title" Decode.string)
(Decode.field "description" Decode.string)
(Decode.field "summary" Decode.string)
(Decode.field "published"
(Decode.string
|> Decode.andThen
@ -136,10 +136,5 @@ view app shared =
(app.data.body
|> Markdown.Renderer.render TailwindMarkdownRenderer.renderer
|> Result.withDefault []
|> processReturn
)
}
processReturn : List (Html Msg) -> List (Html (PagesMsg Msg))
processReturn =
List.map (Html.Styled.map (PagesMsg.fromMsg))

View File

@ -5,6 +5,7 @@ import FatalError exposing (FatalError)
import Head
import Head.Seo as Seo
import Html.Styled as Html
import Html.Styled.Attributes as Attributes
import Link exposing (Link)
import Pages.Url
import PagesMsg exposing (PagesMsg)
@ -77,18 +78,19 @@ view :
-> Shared.Model
-> View (PagesMsg Msg)
view app shared =
{ title = "elm-pages is running"
{ title = "Anh Khoa Nguyen"
, body =
[ Html.h1 [] [ Html.text "elm-pages is up and running!" ]
, Html.p []
[ Html.text <| "The message is: " ++ app.data.message
[ Html.p []
[ Html.text <| "Welcome to my personal website, where I post random things and thoughts."
]
, Link.link (Link.internal (Route.Blog__Slug_ { slug = "a" })) [] [ Html.text "My blog post" ]
, Link.link (Link.internal (Route.Blog__Slug_ { slug = "" })) [] [ Html.text "Blogs" ]
, Html.br [] []
, Link.link (Link.internal (Route.Osx__Slug_ { slug = "" })) [] [ Html.text "OSX Series" ]
, Html.br [] []
, Html.text "Here is my CV:"
, Link.link (Link.external cvpdf) [Attributes.target "_blank"] [Html.text "CV.pdf"]
]
|> processReturn
}
processReturn : List (Html.Html Msg) -> List (Html.Html (PagesMsg Msg))
processReturn =
List.map (Html.map (PagesMsg.fromMsg))
cvpdf : String
cvpdf = "cv.pdf"

113
app/Route/Osx.elm Normal file
View File

@ -0,0 +1,113 @@
module Route.Osx exposing (ActionData, Data, Model, Msg, route)
import Article
import BackendTask exposing (BackendTask)
import Date exposing (Date)
import FatalError exposing (FatalError)
import Head
import Head.Seo as Seo
import Html.Styled exposing (..)
import Html.Styled.Attributes as Attributes
import Json.Decode as Decode exposing (Decoder)
import Json.Decode.Extra
import Pages.Url
import PagesMsg exposing (PagesMsg)
import Route exposing (Route)
import RouteBuilder exposing (App, StatelessRoute)
import Shared
import View exposing (View)
import Link
import Markdown.Block
import Markdown.Renderer
import MarkdownCodec
import TailwindMarkdownRenderer
import Tailwind.Utilities as Tw
type alias Model =
{}
type alias Msg =
()
type alias RouteParams =
{}
route : StatelessRoute RouteParams Data ActionData
route =
RouteBuilder.single
{ head = head
, data = data
}
|> RouteBuilder.buildNoState { view = view }
type alias Data =
List (Route, Article.ArticleMetadata)
type alias ActionData =
{}
data : BackendTask FatalError Data
data =
Article.osxAllMetadata
|> BackendTask.allowFatal
head :
App Data ActionData RouteParams
-> List Head.Tag
head app =
Seo.summary
{ canonicalUrlOverride = Nothing
, siteName = "elm-pages"
, image =
{ url = Pages.Url.external "TODO"
, alt = "elm-pages logo"
, dimensions = Nothing
, mimeType = Nothing
}
, description = "TODO"
, locale = Nothing
, title = "TODO title" -- metadata.title -- TODO
}
|> Seo.website
view :
App Data ActionData RouteParams
-> Shared.Model
-> View msg
view app shared =
{ title = "title"
, body =
[ div []
[ text "For years, I learned how the Apple binary format works."
, text "There are blog posts that I wrote when I first started learning about them."
, text "If you want to read them, here they are below, ported from the efiens blog."
, ul []
(List.map (\item -> li [] [item]) oldBlogs)
, br [] []
, text "I gree my idea in injection into an obfuscation scheme for MachO binary."
, text "In the following whitepaper, I writeup all steps in this obfuscation scheme."
, Link.link (Link.external whitepaper)
[Attributes.target "_blank"]
[text "macho-obfuscation.pdf"]
]
]
}
oldBlogs : List (Html msg)
oldBlogs =
[ (Link.link (Link.internal (Route.Osx__Slug_ { slug = "macho" })) [] [text "Macho"] )
, (Link.link (Link.internal (Route.Osx__Slug_ { slug = "linker" })) [] [text "Linker"] )
, (Link.link (Link.internal (Route.Osx__Slug_ { slug = "fairplay" })) [] [text "Fairplay"] )
, (Link.link (Link.internal (Route.Osx__Slug_ { slug = "inject" })) [] [text "Inject"] )
]
whitepaper : String
whitepaper = "/macho-obfuscation.pdf"

141
app/Route/Osx/Slug_.elm Normal file
View File

@ -0,0 +1,141 @@
module Route.Osx.Slug_ exposing (ActionData, Data, Model, Msg, route)
import Article
import BackendTask exposing (BackendTask)
import Date exposing (Date)
import FatalError exposing (FatalError)
import Head
import Head.Seo as Seo
import Html.Styled exposing (..)
import Json.Decode as Decode exposing (Decoder)
import Json.Decode.Extra
import Pages.Url
import PagesMsg exposing (PagesMsg)
import RouteBuilder exposing (App, StatelessRoute)
import Shared
import View exposing (View)
import Markdown.Block
import Markdown.Renderer
import MarkdownCodec
import TailwindMarkdownRenderer
import Tailwind.Utilities as Tw
type alias Model =
{}
type alias Msg =
()
type alias RouteParams =
{ slug : String }
route : StatelessRoute RouteParams Data ActionData
route =
RouteBuilder.preRender
{ head = head
, pages = pages
, data = data
}
|> RouteBuilder.buildNoState { view = view }
pages : BackendTask FatalError (List RouteParams)
pages =
Article.osxPostsGlob
|> BackendTask.map
(List.map
(\globData ->
{ slug = globData.slug }
)
)
type alias Data =
{ metadata : ArticleMetadata
, body : List Markdown.Block.Block
}
type alias ActionData =
{}
data : RouteParams -> BackendTask FatalError Data
data routeParams =
MarkdownCodec.withFrontmatter Data
frontmatterDecoder
TailwindMarkdownRenderer.renderer
("content/osx/" ++ routeParams.slug ++ ".md")
type alias ArticleMetadata =
{ title : String
, description : String
, published : Date
-- , image : Pages.Url.Url
, draft : Bool
}
frontmatterDecoder : Decoder ArticleMetadata
frontmatterDecoder =
Decode.map4 ArticleMetadata
(Decode.field "title" Decode.string)
(Decode.field "summary" Decode.string)
(Decode.field "published"
(Decode.string
|> Decode.andThen
(\isoString ->
Date.fromIsoString isoString
|> Json.Decode.Extra.fromResult
)
)
)
-- (Decode.oneOf
-- [ Decode.field "image" imageDecoder
-- , Decode.field "unsplash" UnsplashImage.decoder |> Decode.map UnsplashImage.imagePath
-- ]
-- )
(Decode.field "draft" Decode.bool
|> Decode.maybe
|> Decode.map (Maybe.withDefault False)
)
head :
App Data ActionData RouteParams
-> List Head.Tag
head app =
Seo.summary
{ canonicalUrlOverride = Nothing
, siteName = "elm-pages"
, image =
{ url = Pages.Url.external "TODO"
, alt = "elm-pages logo"
, dimensions = Nothing
, mimeType = Nothing
}
, description = "TODO"
, locale = Nothing
, title = "TODO title" -- metadata.title -- TODO
}
|> Seo.website
view :
App Data ActionData RouteParams
-> Shared.Model
-> View (PagesMsg Msg)
view app shared =
{ title = "title"
, body =
(app.data.body
|> Markdown.Renderer.render TailwindMarkdownRenderer.renderer
|> Result.withDefault []
)
}