basic website complete
- ported posts from Efiens - add CV - add MachO obfuscation whitepaper
This commit is contained in:
98
app/Route/Blog.elm
Normal file
98
app/Route/Blog.elm
Normal 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
|
||||
]
|
||||
]
|
||||
]
|
@ -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))
|
||||
|
@ -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
113
app/Route/Osx.elm
Normal 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
141
app/Route/Osx/Slug_.elm
Normal 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 []
|
||||
)
|
||||
}
|
||||
|
Reference in New Issue
Block a user