Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions examples/slack-serverless/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
// ToDo update readme
3 changes: 3 additions & 0 deletions examples/slack-serverless/deploy.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/usr/bin/env bash
export EVERYAUTH_TOKEN=$(everyauth token -e 10y)
sls deploy
91 changes: 91 additions & 0 deletions examples/slack-serverless/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
const express = require('express');
const serverless = require('serverless-http');
const { v4: uuidv4 } = require('uuid');
const cookieSession = require('cookie-session');

const { WebClient } = require('@slack/web-api');

const everyauth = require('@fusebit/everyauth-express');

const app = express();
const port = 3000;

app.use(express.json());
app.use(express.urlencoded({ extended: true }));

// Get userId from the authorization redirect or via session if already authorized.
const validateSession = (req, res, next) => {
if (req.query.userId) {
req.session.userId = req.query.userId;
}
if (!req.session.userId) {
return res.redirect('/dev/');
}
return next();
};

app.use(
cookieSession({
name: 'session',
secret: 'secret',
})
);

app.set('view engine', 'pug');

app.get('/', (req, res) => {
if (!req.session.userId) {
return res.redirect(`/dev/authorize/${uuidv4()}`);
}
res.redirect('/dev/finished');
});

app.use(
'/authorize/:userId',
(req, res, next) => {
if (!req.params.userId) {
return res.redirect('/dev/');
}
return next();
},
everyauth.authorize('slack', {
// The endpoint of your app where control will be returned afterwards
finishedUrl: '/dev/finished',
hostedBaseUrl: (req) =>
`https://${req.requestContext.domainName}/${req.requestContext.stage}/authorize/${req.session.userId}`,
// The user ID of the authenticated user the credentials will be associated with
mapToUserId: (req) => req.params.userId,
})
);

app.get('/finished', validateSession, async (req, res) => {
const userCredentials = await everyauth.getIdentity('slack', req.session.userId);
// Call Slack API
const slackClient = new WebClient(userCredentials.accessToken);
const userResponse = await slackClient.users.info({ user: userCredentials.native.authed_user.id });
res.render('index', { title: 'user profile', user: userResponse.user });
});

app.post('/message', validateSession, async (req, res) => {
const userCredentials = await everyauth.getIdentity('slack', req.session.userId);
// Call Slack API
const slackClient = new WebClient(userCredentials.accessToken);
const userResponse = await slackClient.users.info({ user: userCredentials.native.authed_user.id });
const message = req.body.message;

if (message) {
await slackClient.chat.postMessage({
text: message,
channel: userCredentials.native.authed_user.id,
});
}

res.render('index', {
title: 'user profile',
user: userResponse.user,
messageSent: !!message,
message: req.body.message || 'Please write a message',
});
});

module.exports.handler = serverless(app);
22 changes: 22 additions & 0 deletions examples/slack-serverless/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"name": "everyauth-slack",
"private": true,
"version": "1.0.0",
"description": "Use Slack API with EveryAuth",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "Fusebit, Inc.",
"license": "ISC",
"dependencies": {
"@fusebit/everyauth-express": "^2.0.4",
"@slack/web-api": "^6.7.1",
"cookie-session": "^2.0.0",
"express": "^4.17.3",
"pug": "^3.0.2",
"serverless-http": "^3.0.1",
"uuid": "^8.3.2"
}
}
17 changes: 17 additions & 0 deletions examples/slack-serverless/serverless.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
org: fusebitdemo
app: everyauth-slack-demo
service: everyauth-slack-demo

provider:
name: aws
runtime: nodejs14.x
region: us-west-1

functions:
app:
handler: index.handler
events:
- http: ANY /
- http: "ANY /{proxy+}"
environment:
EVERYAUTH_TOKEN: ${env:EVERYAUTH_TOKEN}
31 changes: 31 additions & 0 deletions examples/slack-serverless/views/index.pug
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
html
head
title=title
style
include ./style.css
script(src='https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/js/all.min.js' defer integrity="sha512-6PM0qYu5KExuNcKt5bURAoT6KCThUmHRewN3zUFNaoI6Di7XJPTMoT6K0nsagZKk2OB4L7E3q1uQKHNHd4stIQ==" crossorigin="anonymous")
body
.profile
.pic-container
img.pic(src=user.profile.image_1024 alt='Slack Avatar')
span.hi-icon
i(class="fa-solid fa-shake fa-hand-peace")
h2=user.real_name
p=user.profile.title
p.send-me='You can send me a message from here, I will get it directly in my Slack!'
.form-container
unless !messageSent
p.success
i(class="fa-solid fa-bounce fa-wand-magic-sparkles")
span='Thanks!, I got your message:'
unless !message
p.message-text
span=message
a.button(href='/dev/') Go back
unless messageSent
form(action="/dev/message" method="post")
textarea(name="message", cols="30", rows="10")
.send-area
button.send-button(action='submit')
i(class="fa-solid fa-bounce fa-comment")
span='Send me a message'
117 changes: 117 additions & 0 deletions examples/slack-serverless/views/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
/* Global */
* {
margin: 0;
padding: 0;
}

body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif, 'Apple Color Emoji',
'Segoe UI Emoji';
background-color: #c3c9cf;
}

body,
a {
color: #fff;
}

h1 span {
font-size: 20px;
font-style: normal;
font-weight: 300;
line-height: 24px;
}

/* GitHub profile section */
.profile {
background-color: #30363d;
text-align: center;
box-shadow: 0px 1px 7px 3px #707a85;
width: 400px;
margin: 20px auto;
border-radius: 10px;
}

.profile .pic {
height: 200px;
width: 200px;
border-radius: 50%;
margin: auto auto 10px auto;
display: block;
box-shadow: 0 0 0 1px rgba(240, 246, 252, 0.1);
}

/* Public repository listing section */
.message {
background-color: #30363ced;
width: 60%;
margin-left: 41%;
}

.success {
background-color: #237d23;
padding: 10px;
}

.form-container {
border-top: solid 1px #707a85;
background-color: gray;
border-radius: 0 0 10px 10px;
padding-top: 10px;
margin-top: 20px;
min-height: 100px;
}

textarea {
width: 100%;
padding: 10px;
}
.send-button,
.button {
background-color: #373737;
color: #fff;
padding: 10px;
border: none;
margin: 5px;
border-radius: 50px;
box-shadow: 2px 3px 7px 0px #564d4d;
}

.button {
display: block;
text-decoration: none;
margin-bottom: 10px;
}

.send-button svg,
.button svg,
.success svg {
padding-right: 5px;
}

.hi-icon {
color: yellow;
font-size: 50px;
}

.send-me {
margin-top: 10px;
border-top: solid 1px #707a85;
padding-top: 10px;
font-size: 10px;
}

.pic-container {
padding-top: 10px;
}

a,
button {
cursor: pointer;
}

.message-text {
background-color: #fff;
color: #707a85;
padding: 10px;
}