@x-sls/google-auth 1.0.1 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@x-sls/google-auth",
3
- "version": "1.0.1",
3
+ "version": "1.1.0",
4
4
  "main": "src/index.js",
5
5
  "scripts": {},
6
6
  "dependencies": {
package/src/client.js CHANGED
@@ -1,63 +1,60 @@
1
- function createClient({
1
+ const createAuthUrl = ({ GOOGLE_CLIENT_ID, REDIRECT_URI, state = {} }) =>
2
+ `https://accounts.google.com/o/oauth2/v2/auth?client_id=${GOOGLE_CLIENT_ID}&redirect_uri=${REDIRECT_URI}&response_type=code&scope=profile+email&state=${encodeURIComponent(JSON.stringify(state))}`
3
+
4
+ const getAccessToken = async ({
2
5
  GOOGLE_CLIENT_ID,
3
6
  GOOGLE_CLIENT_SECRET,
4
- REDIRECT_URI
5
- }) {
6
- const createAuthUrl = () =>
7
- `https://accounts.google.com/o/oauth2/v2/auth?client_id=${GOOGLE_CLIENT_ID}&redirect_uri=${REDIRECT_URI}&response_type=code&scope=profile email`
8
-
9
- const getAccessToken = async ({ code }) => {
10
- let text
11
- try {
12
- const res = await fetch('https://oauth2.googleapis.com/token', {
13
- method: 'POST',
14
- headers: {
15
- 'Content-Type': 'application/json'
16
- },
17
- body: JSON.stringify({
18
- client_id: GOOGLE_CLIENT_ID,
19
- client_secret: GOOGLE_CLIENT_SECRET,
20
- code,
21
- redirect_uri: REDIRECT_URI,
22
- grant_type: 'authorization_code'
23
- })
7
+ REDIRECT_URI,
8
+ code
9
+ }) => {
10
+ let text
11
+ try {
12
+ const res = await fetch('https://oauth2.googleapis.com/token', {
13
+ method: 'POST',
14
+ headers: {
15
+ 'Content-Type': 'application/json'
16
+ },
17
+ body: JSON.stringify({
18
+ client_id: GOOGLE_CLIENT_ID,
19
+ client_secret: GOOGLE_CLIENT_SECRET,
20
+ code,
21
+ redirect_uri: REDIRECT_URI,
22
+ grant_type: 'authorization_code'
24
23
  })
24
+ })
25
25
 
26
- text = await res.text()
26
+ text = await res.text()
27
27
 
28
- return JSON.parse(text)
29
- } catch (error) {
30
- if (text) {
31
- console.error({ text })
32
- }
33
- throw error
28
+ return JSON.parse(text)
29
+ } catch (error) {
30
+ if (text) {
31
+ console.error({ text })
34
32
  }
33
+ throw error
35
34
  }
35
+ }
36
36
 
37
- const getUserInfo = async ({ access_token }) => {
38
- let text
39
- try {
40
- const res = await fetch('https://www.googleapis.com/oauth2/v1/userinfo', {
41
- headers: {
42
- Authorization: `Bearer ${access_token}`
43
- }
44
- })
45
-
46
- text = await res.text()
47
- return JSON.parse(text)
48
- } catch (error) {
49
- if (text) {
50
- console.error({ text })
37
+ const getUserInfo = async ({ access_token }) => {
38
+ let text
39
+ try {
40
+ const res = await fetch('https://www.googleapis.com/oauth2/v1/userinfo', {
41
+ headers: {
42
+ Authorization: `Bearer ${access_token}`
51
43
  }
52
- throw error
53
- }
54
- }
44
+ })
55
45
 
56
- return {
57
- getUserInfo,
58
- getAccessToken,
59
- createAuthUrl
46
+ text = await res.text()
47
+ return JSON.parse(text)
48
+ } catch (error) {
49
+ if (text) {
50
+ console.error({ text })
51
+ }
52
+ throw error
60
53
  }
61
54
  }
62
55
 
63
- module.exports = createClient
56
+ module.exports = {
57
+ createAuthUrl,
58
+ getAccessToken,
59
+ getUserInfo
60
+ }
package/src/handlers.js CHANGED
@@ -1,82 +1,115 @@
1
1
  const jwt = require('jsonwebtoken')
2
+ const { createAuthUrl, getAccessToken, getUserInfo } = require('./client')
2
3
 
3
- const { createAuthUrl, getAccessToken, getUserInfo } = require('./index')
4
+ function initiate({ GOOGLE_CLIENT_ID, REDIRECT_URI }) {
5
+ return event => {
6
+ const { returnUrl } = event?.queryStringParameters || {}
4
7
 
5
- async function initiate() {
6
- return {
7
- statusCode: 302,
8
- headers: {
9
- Location: createAuthUrl({ GOOGLE_CLIENT_ID, REDIRECT_URI })
8
+ const state = { returnUrl }
9
+ return {
10
+ statusCode: 302,
11
+ headers: {
12
+ Location: createAuthUrl({
13
+ GOOGLE_CLIENT_ID,
14
+ REDIRECT_URI,
15
+ state
16
+ })
17
+ }
10
18
  }
11
19
  }
12
20
  }
13
21
 
14
- async function callback(event) {
15
- const { code } = event.queryStringParameters
16
- const headers = {
17
- 'Access-Control-Allow-Origin': '*',
18
- 'Access-Control-Allow-Credentials': true,
19
- 'Access-Control-Allow-Headers': 'Content-Type, Authorization'
20
- }
22
+ function callback({
23
+ GOOGLE_CLIENT_ID,
24
+ GOOGLE_CLIENT_SECRET,
25
+ JWT_SECRET,
26
+ REDIRECT_URI,
27
+ isUserAllowed
28
+ }) {
29
+ return async event => {
30
+ const { code, state } = event.queryStringParameters
31
+
32
+ let returnUrl
33
+ try {
34
+ const data = JSON.parse(state)
35
+ returnUrl = data.returnUrl
36
+ } catch (error) {
37
+ console.error('Invalid state:', state)
38
+ returnUrl = '/'
39
+ }
21
40
 
22
- try {
23
- const { access_token } = await getAccessToken({
24
- code,
25
- GOOGLE_CLIENT_ID,
26
- GOOGLE_CLIENT_SECRET,
27
- REDIRECT_URI
28
- })
29
- const info = await getUserInfo({ access_token })
41
+ try {
42
+ const { access_token } = await getAccessToken({
43
+ code,
44
+ GOOGLE_CLIENT_ID,
45
+ GOOGLE_CLIENT_SECRET,
46
+ REDIRECT_URI
47
+ })
48
+ const info = await getUserInfo({ access_token })
30
49
 
31
- const { email, name, picture } = info
32
- const sessionToken = jwt.sign(
33
- {
34
- email,
35
- name,
36
- picture
37
- },
38
- JWT_SECRET,
39
- { expiresIn: '1d' }
40
- )
50
+ const { email, name, picture } = info
41
51
 
42
- console.log({ sessionToken })
52
+ const isAllowed = await isUserAllowed(email)
53
+ if (!isAllowed) {
54
+ throw new Error('Contact admin for access.')
55
+ }
43
56
 
44
- return {
45
- statusCode: 200,
46
- headers,
47
- body: JSON.stringify({ token: sessionToken })
48
- }
49
- } catch (error) {
50
- console.error('Error:', error)
51
- return {
52
- statusCode: 401,
53
- headers,
54
- body: JSON.stringify({ error: 'Authentication failed' })
57
+ const sessionToken = jwt.sign(
58
+ {
59
+ email,
60
+ name,
61
+ picture
62
+ },
63
+ JWT_SECRET,
64
+ { expiresIn: '1d' }
65
+ )
66
+
67
+ return {
68
+ statusCode: 302,
69
+ headers: {
70
+ Location: `${returnUrl}#token=${sessionToken}`
71
+ }
72
+ }
73
+ } catch (error) {
74
+ console.error('Error:', error)
75
+ return {
76
+ statusCode: 302,
77
+ headers: {
78
+ Location: `${returnUrl}#authError=${error}`
79
+ }
80
+ }
55
81
  }
56
82
  }
57
83
  }
58
84
 
59
- async function verify(event) {
60
- try {
61
- const { token } = JSON.parse(event.body)
62
- const decoded = jwt.verify(token, JWT_SECRET)
85
+ function verify({ JWT_SECRET, isUserAllowed }) {
86
+ return async event => {
87
+ try {
88
+ const { token } = JSON.parse(event.body)
89
+ const decoded = jwt.verify(token, JWT_SECRET)
63
90
 
64
- return {
65
- statusCode: 200,
66
- headers: {
67
- 'Access-Control-Allow-Origin': '*',
68
- 'Access-Control-Allow-Credentials': true
69
- },
70
- body: JSON.stringify({ user: decoded })
71
- }
72
- } catch (error) {
73
- return {
74
- statusCode: 401,
75
- headers: {
76
- 'Access-Control-Allow-Origin': '*',
77
- 'Access-Control-Allow-Credentials': true
78
- },
79
- body: JSON.stringify({ error: 'Invalid token' })
91
+ const isAllowed = await isUserAllowed(decoded.email)
92
+ if (!isAllowed) {
93
+ throw new Error('Contact admin for access.')
94
+ }
95
+
96
+ return {
97
+ statusCode: 200,
98
+ headers: {
99
+ 'Access-Control-Allow-Origin': '*',
100
+ 'Access-Control-Allow-Credentials': true
101
+ },
102
+ body: JSON.stringify({ user: decoded })
103
+ }
104
+ } catch (error) {
105
+ return {
106
+ statusCode: 401,
107
+ headers: {
108
+ 'Access-Control-Allow-Origin': '*',
109
+ 'Access-Control-Allow-Credentials': true
110
+ },
111
+ body: JSON.stringify({ error: error.message })
112
+ }
80
113
  }
81
114
  }
82
115
  }
package/src/index.js CHANGED
@@ -1,7 +1,7 @@
1
- const jwt = require('jsonwebtoken')
2
- const createClient = require('./client')
1
+ const client = require('./client')
2
+ const handlers = require('./handlers')
3
3
 
4
4
  module.exports = {
5
- createClient,
6
- jwt
5
+ client,
6
+ handlers
7
7
  }