Last active
August 5, 2016 23:29
-
-
Save lukewestby/ceed6381551530c81ee479a8dc5033f1 to your computer and use it in GitHub Desktop.
OAuth 1.0a (3-legged flow) with Elm and Node
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
port module Main exposing (..) | |
import Html exposing (..) | |
import Html.App as Html | |
import Html.Attributes exposing (..) | |
import Html.Events exposing (..) | |
type LoginState | |
= Waiting | |
| LoggedIn | |
| LoggedOut | |
type alias Model = | |
{ loginState : LoginState } | |
loginStateFromBool : Bool -> LoginState | |
loginStateFromBool loggedIn = | |
if loggedIn then | |
LoggedIn | |
else | |
LoggedOut | |
type Msg | |
= LoginStart | |
| LoginComplete Bool | |
update : Msg -> Model -> (Model, Cmd Msg) | |
update msg model = | |
case msg of | |
LoginStart -> | |
( { loginState = Waiting } | |
, loginStart () | |
) | |
LoginComplete loggedIn -> | |
( { loginState = loginStateFromBool loggedIn } | |
, Cmd.none | |
) | |
port loginStart : () -> Cmd msg | |
port loginComplete : (Bool -> msg) -> Sub msg | |
subscriptions : Model -> Sub Msg | |
subscriptions model = | |
case model.loginState of | |
Waiting -> | |
loginComplete LoginComplete | |
_ -> | |
Sub.none | |
init : { loggedIn : Bool } -> (Model, Cmd Msg) | |
init { loggedIn } = | |
( { loginState = loginStateFromBool loggedIn } | |
, Cmd.none | |
) | |
view : Model -> Html Msg | |
view model = | |
case model.loginState of | |
Waiting -> | |
text "Logging in ..." | |
LoggedIn -> | |
text "Logged in!" | |
Loggedout -> | |
button [ onClick LoginStart ] | |
[ text "Log in to Twitter" ] | |
main : Program { loggedIn : Bool } | |
main = | |
Html.programWithFlag | |
{ init = init | |
, update = update | |
, subscriptions = subscriptions | |
, view = view | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const express = require('express') | |
, logger = require('morgan') | |
, session = require('express-session') | |
, bodyParser = require('body-parser') | |
, path = require('path') | |
, Grant = require('grant-express') | |
const grant = new Grant({ | |
server: { | |
protocol: process.env.PROTOCOL, | |
host: protocol.env.URL, | |
}, | |
twitter: { | |
key: process.env.CONSUMER_KEY, | |
secret: process.env.CONSUMER_SECRET, | |
callback: '/handle_twitter_callback' | |
} | |
}) | |
const app = express() | |
app.use(express.static(path.join(__dirname, '../build'))) | |
app.use(logger('dev')) | |
app.use(session({ secret: process.env.SESSION_SECRET })) | |
app.use(grant) | |
app.use(bodyParser.json()) | |
app.get('/handle_twitter_callback', function (req, res) { | |
if (req.query.error) { | |
req.session.auth = null | |
} else { | |
req.session.auth = req.query | |
} | |
res.send( | |
`<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="utf-8" /> | |
</head> | |
<body> | |
<script> | |
window.opener.postMessage( | |
${!!req.user.auth}, | |
'${process.env.PROTOCOL}://${process.env.URL}' | |
) | |
window.close() | |
</script> | |
</body> | |
</html> | |
` | |
) | |
}) | |
app.get('/', (req, res) => { | |
res.send( | |
`<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="utf-8" /> | |
<meta name="viewport" content="user-scalable=no,initial-scale=1,minimum-scale=1,maximum-scale=1,width=device-width" /> | |
<link href='https://fonts.googleapis.com/css?family=Source+Sans+Pro:400,300,600' rel='stylesheet' type='text/css'> | |
<link rel="stylesheet" href="main.css" /> | |
</head> | |
<body> | |
<script src="main.js"></script> | |
<script> | |
var app = Elm.Main.fullscreen({ | |
loggedIn: ${!!req.session.auth} | |
}) | |
window.addEventListener('message', function(e) { | |
app.ports.loginComplete.send(e.data) | |
}) | |
app.ports.loginStart.subscribe(function() { | |
window.open('/connect/twitter') | |
}) | |
</script> | |
</body> | |
</html> | |
` | |
) | |
}) | |
app.listen(process.env.PORT, function() { | |
console.log(`Express server listening on port ${process.env.PORT}`) | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment