webpush 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 6e8453b2c3a66c07ce852d302a8661cfd5f59771
4
+ data.tar.gz: 97441485cfaea8a1d66f6460367758a40b593409
5
+ SHA512:
6
+ metadata.gz: 49e9087ac49e17c2c4a23e4fcca7171aa8c6f735024e0c78328ece944d6d2b2cdda15ba72ab51d662823196b85dec23b83c170afccb7fbfe8a58e47ec81d9d75
7
+ data.tar.gz: b887988ec3389600c854a9c6693bb336d1acaf9748734167eb56005c98b80392417ff37de74e7b9fc503669396cde8bdd484130f93f6f11bd217c5bc8da62392
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
@@ -0,0 +1 @@
1
+ webpush
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <Settings><!--This file was automatically generated by Ruby plugin.
3
+ You are allowed to:
4
+ 1. Remove rake task
5
+ 2. Add existing rake tasks
6
+ To add existing rake tasks automatically delete this file and reload the project.
7
+ --><RakeGroup description="" fullCmd="" taksId="rake" /></Settings>
@@ -0,0 +1,14 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="ProjectLevelVcsManager" settingsEditedManually="false">
4
+ <OptionsSetting value="true" id="Add" />
5
+ <OptionsSetting value="true" id="Remove" />
6
+ <OptionsSetting value="true" id="Checkout" />
7
+ <OptionsSetting value="true" id="Update" />
8
+ <OptionsSetting value="true" id="Status" />
9
+ <OptionsSetting value="true" id="Edit" />
10
+ <ConfirmationsSetting value="0" id="Add" />
11
+ <ConfirmationsSetting value="0" id="Remove" />
12
+ </component>
13
+ <component name="ProjectRootManager" version="2" project-jdk-name="ruby-2.0.0-p451" project-jdk-type="RUBY_SDK" />
14
+ </project>
@@ -0,0 +1,8 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="ProjectModuleManager">
4
+ <modules>
5
+ <module fileurl="file://$PROJECT_DIR$/.idea/webpush.iml" filepath="$PROJECT_DIR$/.idea/webpush.iml" />
6
+ </modules>
7
+ </component>
8
+ </project>
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="VcsDirectoryMappings">
4
+ <mapping directory="$PROJECT_DIR$" vcs="Git" />
5
+ </component>
6
+ </project>
@@ -0,0 +1,19 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <module type="RUBY_MODULE" version="4">
3
+ <component name="FacetManager">
4
+ <facet type="gem" name="Ruby Gem">
5
+ <configuration>
6
+ <option name="GEM_APP_ROOT_PATH" value="$MODULE_DIR$" />
7
+ <option name="GEM_APP_TEST_PATH" value="" />
8
+ <option name="GEM_APP_LIB_PATH" value="$MODULE_DIR$/lib" />
9
+ </configuration>
10
+ </facet>
11
+ </component>
12
+ <component name="NewModuleRootManager">
13
+ <content url="file://$MODULE_DIR$" />
14
+ <orderEntry type="inheritedJdk" />
15
+ <orderEntry type="sourceFolder" forTests="false" />
16
+ <orderEntry type="library" scope="PROVIDED" name="diff-lcs (v1.2.5, ruby-2.0.0-p451) [gem]" level="application" />
17
+ <orderEntry type="library" scope="PROVIDED" name="rake (v10.3.2, ruby-2.0.0-p451) [gem]" level="application" />
18
+ </component>
19
+ </module>
@@ -0,0 +1,347 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="ChangeListManager">
4
+ <list default="true" id="92478032-adc2-4ebf-bd18-29b0175af59f" name="Default" comment="">
5
+ <change type="DELETED" beforePath="$PROJECT_DIR$/lib/web_push_encryption.rb" afterPath="" />
6
+ <change type="DELETED" beforePath="$PROJECT_DIR$/lib/web_push_encryption/version.rb" afterPath="" />
7
+ <change type="DELETED" beforePath="$PROJECT_DIR$/spec/web_push_encryption_spec.rb" afterPath="" />
8
+ <change type="DELETED" beforePath="$PROJECT_DIR$/web_push_encryption.gemspec" afterPath="" />
9
+ <change type="MODIFICATION" beforePath="$PROJECT_DIR$/Gemfile" afterPath="$PROJECT_DIR$/Gemfile" />
10
+ <change type="MODIFICATION" beforePath="$PROJECT_DIR$/README.md" afterPath="$PROJECT_DIR$/README.md" />
11
+ <change type="MODIFICATION" beforePath="$PROJECT_DIR$/bin/console" afterPath="$PROJECT_DIR$/bin/console" />
12
+ <change type="MODIFICATION" beforePath="$PROJECT_DIR$/spec/spec_helper.rb" afterPath="$PROJECT_DIR$/spec/spec_helper.rb" />
13
+ </list>
14
+ <ignored path="webpush.iws" />
15
+ <ignored path=".idea/workspace.xml" />
16
+ <ignored path=".idea/dataSources.local.xml" />
17
+ <option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
18
+ <option name="TRACKING_ENABLED" value="true" />
19
+ <option name="SHOW_DIALOG" value="false" />
20
+ <option name="HIGHLIGHT_CONFLICTS" value="true" />
21
+ <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
22
+ <option name="LAST_RESOLUTION" value="IGNORE" />
23
+ </component>
24
+ <component name="ChangesViewManager" flattened_view="true" show_ignored="false" />
25
+ <component name="CreatePatchCommitExecutor">
26
+ <option name="PATCH_PATH" value="" />
27
+ </component>
28
+ <component name="ExecutionTargetManager" SELECTED_TARGET="default_target" />
29
+ <component name="FavoritesManager">
30
+ <favorites_list name="webpush" />
31
+ </component>
32
+ <component name="FileEditorManager">
33
+ <leaf>
34
+ <file leaf-file-name="Gemfile" pinned="false" current-in-tab="false">
35
+ <entry file="file://$PROJECT_DIR$/Gemfile">
36
+ <provider selected="true" editor-type-id="text-editor">
37
+ <state vertical-scroll-proportion="0.0">
38
+ <caret line="4" column="0" selection-start-line="4" selection-start-column="0" selection-end-line="4" selection-end-column="0" />
39
+ <folding />
40
+ </state>
41
+ </provider>
42
+ </entry>
43
+ </file>
44
+ <file leaf-file-name="Rakefile" pinned="false" current-in-tab="false">
45
+ <entry file="file://$PROJECT_DIR$/Rakefile">
46
+ <provider selected="true" editor-type-id="text-editor">
47
+ <state vertical-scroll-proportion="0.0">
48
+ <caret line="3" column="32" selection-start-line="3" selection-start-column="32" selection-end-line="3" selection-end-column="32" />
49
+ <folding />
50
+ </state>
51
+ </provider>
52
+ </entry>
53
+ </file>
54
+ <file leaf-file-name="webpush.gemspec" pinned="false" current-in-tab="false">
55
+ <entry file="file://$PROJECT_DIR$/webpush.gemspec">
56
+ <provider selected="true" editor-type-id="text-editor">
57
+ <state vertical-scroll-proportion="0.0">
58
+ <caret line="18" column="0" selection-start-line="18" selection-start-column="0" selection-end-line="18" selection-end-column="0" />
59
+ <folding />
60
+ </state>
61
+ </provider>
62
+ </entry>
63
+ </file>
64
+ <file leaf-file-name="setup" pinned="false" current-in-tab="false">
65
+ <entry file="file://$PROJECT_DIR$/bin/setup">
66
+ <provider selected="true" editor-type-id="text-editor">
67
+ <state vertical-scroll-proportion="0.0">
68
+ <caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
69
+ <folding />
70
+ </state>
71
+ </provider>
72
+ </entry>
73
+ </file>
74
+ <file leaf-file-name="version.rb" pinned="false" current-in-tab="true">
75
+ <entry file="file://$PROJECT_DIR$/lib/webpush/version.rb">
76
+ <provider selected="true" editor-type-id="text-editor">
77
+ <state vertical-scroll-proportion="0.06676558">
78
+ <caret line="3" column="0" selection-start-line="3" selection-start-column="0" selection-end-line="3" selection-end-column="0" />
79
+ <folding />
80
+ </state>
81
+ </provider>
82
+ </entry>
83
+ </file>
84
+ </leaf>
85
+ </component>
86
+ <component name="Git.Settings">
87
+ <option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
88
+ </component>
89
+ <component name="IdeDocumentHistory">
90
+ <option name="CHANGED_PATHS">
91
+ <list>
92
+ <option value="$PROJECT_DIR$/lib/webpush/version.rb" />
93
+ </list>
94
+ </option>
95
+ </component>
96
+ <component name="JsBuildToolGruntFileManager" detection-done="true" />
97
+ <component name="JsGulpfileManager">
98
+ <detection-done>true</detection-done>
99
+ </component>
100
+ <component name="NamedScopeManager">
101
+ <order />
102
+ </component>
103
+ <component name="ProjectFrameBounds">
104
+ <option name="x" value="457" />
105
+ <option name="y" value="60" />
106
+ <option name="width" value="1502" />
107
+ <option name="height" value="1165" />
108
+ </component>
109
+ <component name="ProjectLevelVcsManager" settingsEditedManually="false">
110
+ <OptionsSetting value="true" id="Add" />
111
+ <OptionsSetting value="true" id="Remove" />
112
+ <OptionsSetting value="true" id="Checkout" />
113
+ <OptionsSetting value="true" id="Update" />
114
+ <OptionsSetting value="true" id="Status" />
115
+ <OptionsSetting value="true" id="Edit" />
116
+ <ConfirmationsSetting value="0" id="Add" />
117
+ <ConfirmationsSetting value="0" id="Remove" />
118
+ </component>
119
+ <component name="ProjectView">
120
+ <navigator currentView="ProjectPane" proportions="" version="1">
121
+ <flattenPackages />
122
+ <showMembers />
123
+ <showModules />
124
+ <showLibraryContents />
125
+ <hideEmptyPackages />
126
+ <abbreviatePackageNames />
127
+ <autoscrollToSource />
128
+ <autoscrollFromSource />
129
+ <sortByType />
130
+ </navigator>
131
+ <panes>
132
+ <pane id="ProjectPane">
133
+ <subPane>
134
+ <PATH>
135
+ <PATH_ELEMENT>
136
+ <option name="myItemId" value="webpush" />
137
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
138
+ </PATH_ELEMENT>
139
+ </PATH>
140
+ <PATH>
141
+ <PATH_ELEMENT>
142
+ <option name="myItemId" value="webpush" />
143
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
144
+ </PATH_ELEMENT>
145
+ <PATH_ELEMENT>
146
+ <option name="myItemId" value="webpush" />
147
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
148
+ </PATH_ELEMENT>
149
+ </PATH>
150
+ <PATH>
151
+ <PATH_ELEMENT>
152
+ <option name="myItemId" value="webpush" />
153
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
154
+ </PATH_ELEMENT>
155
+ <PATH_ELEMENT>
156
+ <option name="myItemId" value="webpush" />
157
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
158
+ </PATH_ELEMENT>
159
+ <PATH_ELEMENT>
160
+ <option name="myItemId" value="spec" />
161
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
162
+ </PATH_ELEMENT>
163
+ </PATH>
164
+ <PATH>
165
+ <PATH_ELEMENT>
166
+ <option name="myItemId" value="webpush" />
167
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
168
+ </PATH_ELEMENT>
169
+ <PATH_ELEMENT>
170
+ <option name="myItemId" value="webpush" />
171
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
172
+ </PATH_ELEMENT>
173
+ <PATH_ELEMENT>
174
+ <option name="myItemId" value="lib" />
175
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
176
+ </PATH_ELEMENT>
177
+ </PATH>
178
+ <PATH>
179
+ <PATH_ELEMENT>
180
+ <option name="myItemId" value="webpush" />
181
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
182
+ </PATH_ELEMENT>
183
+ <PATH_ELEMENT>
184
+ <option name="myItemId" value="webpush" />
185
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
186
+ </PATH_ELEMENT>
187
+ <PATH_ELEMENT>
188
+ <option name="myItemId" value="lib" />
189
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
190
+ </PATH_ELEMENT>
191
+ <PATH_ELEMENT>
192
+ <option name="myItemId" value="webpush" />
193
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
194
+ </PATH_ELEMENT>
195
+ </PATH>
196
+ <PATH>
197
+ <PATH_ELEMENT>
198
+ <option name="myItemId" value="webpush" />
199
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
200
+ </PATH_ELEMENT>
201
+ <PATH_ELEMENT>
202
+ <option name="myItemId" value="webpush" />
203
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
204
+ </PATH_ELEMENT>
205
+ <PATH_ELEMENT>
206
+ <option name="myItemId" value="bin" />
207
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
208
+ </PATH_ELEMENT>
209
+ </PATH>
210
+ </subPane>
211
+ </pane>
212
+ <pane id="Scope" />
213
+ <pane id="Scratches" />
214
+ </panes>
215
+ </component>
216
+ <component name="PropertiesComponent">
217
+ <property name="last_opened_file_path" value="$PROJECT_DIR$" />
218
+ <property name="WebServerToolWindowFactoryState" value="false" />
219
+ </component>
220
+ <component name="RunManager">
221
+ <configuration default="true" type="CucumberRunConfigurationType" factoryName="Cucumber">
222
+ <predefined_log_file id="RUBY_CUCUMBER" enabled="true" />
223
+ <module name="" />
224
+ <CUCUMBER_RUN_CONFIG_SETTINGS_ID NAME="RUBY_ARGS" VALUE="-e $stdout.sync=true;$stderr.sync=true;load($0=ARGV.shift)" />
225
+ <CUCUMBER_RUN_CONFIG_SETTINGS_ID NAME="WORK DIR" VALUE="" />
226
+ <CUCUMBER_RUN_CONFIG_SETTINGS_ID NAME="SHOULD_USE_SDK" VALUE="false" />
227
+ <CUCUMBER_RUN_CONFIG_SETTINGS_ID NAME="ALTERN_SDK_NAME" VALUE="" />
228
+ <CUCUMBER_RUN_CONFIG_SETTINGS_ID NAME="myPassParentEnvs" VALUE="true" />
229
+ <envs />
230
+ <EXTENSION ID="BundlerRunConfigurationExtension" bundleExecEnabled="false" />
231
+ <EXTENSION ID="JRubyRunConfigurationExtension" NailgunExecEnabled="false" />
232
+ <EXTENSION ID="RubyCoverageRunConfigurationExtension" enabled="false" sample_coverage="true" track_test_folders="true" runner="rcov">
233
+ <COVERAGE_PATTERN ENABLED="true">
234
+ <PATTERN REGEXPS="/.rvm/" INCLUDED="false" />
235
+ </COVERAGE_PATTERN>
236
+ </EXTENSION>
237
+ <EXTENSION ID="org.jetbrains.plugins.ruby.motion.run.MotionSimulatorRunExtension" />
238
+ <CUCUMBER_RUN_CONFIG_SETTINGS_ID NAME="TEST_FILE_MASK" VALUE="**/*.feature" />
239
+ <CUCUMBER_RUN_CONFIG_SETTINGS_ID NAME="TEST_TEST_TYPE" VALUE="TEST_SCRIPT" />
240
+ <CUCUMBER_RUN_CONFIG_SETTINGS_ID NAME="TESTS_FOLDER_PATH" VALUE="" />
241
+ <CUCUMBER_RUN_CONFIG_SETTINGS_ID NAME="TEST_SCRIPT_PATH" VALUE="" />
242
+ <CUCUMBER_RUN_CONFIG_SETTINGS_ID NAME="TEST_TAGS_FILTER" VALUE="" />
243
+ <CUCUMBER_RUN_CONFIG_SETTINGS_ID NAME="TEST_NAME_FILTER" VALUE="" />
244
+ <CUCUMBER_RUN_CONFIG_SETTINGS_ID NAME="CUCUMBER_ARGS" VALUE="--color -r features" />
245
+ <CUCUMBER_RUN_CONFIG_SETTINGS_ID NAME="RUNNER_VERSION" VALUE="" />
246
+ <CUCUMBER_RUN_CONFIG_SETTINGS_ID NAME="FULL_BACKTRACE" VALUE="false" />
247
+ <CUCUMBER_RUN_CONFIG_SETTINGS_ID NAME="VERBOSE_OPTION" VALUE="false" />
248
+ <CUCUMBER_RUN_CONFIG_SETTINGS_ID NAME="DRB" VALUE="false" />
249
+ <CUCUMBER_RUN_CONFIG_SETTINGS_ID NAME="ZEUS" VALUE="false" />
250
+ <CUCUMBER_RUN_CONFIG_SETTINGS_ID NAME="SPRING" VALUE="false" />
251
+ <CUCUMBER_RUN_CONFIG_SETTINGS_ID NAME="CUCUMBER_RUNNER_PATH" VALUE="" />
252
+ <CUCUMBER_RUN_CONFIG_SETTINGS_ID NAME="USE_CUSTOM_RUNNER" VALUE="false" />
253
+ <CUCUMBER_RUN_CONFIG_SETTINGS_ID NAME="SETTINGS_VERSION" VALUE="2" />
254
+ <method />
255
+ </configuration>
256
+ <configuration default="true" type="JavascriptDebugType" factoryName="JavaScript Debug">
257
+ <method />
258
+ </configuration>
259
+ <configuration default="true" type="js.build_tools.gulp" factoryName="Gulp.js">
260
+ <method />
261
+ </configuration>
262
+ </component>
263
+ <component name="ShelveChangesManager" show_recycled="false" />
264
+ <component name="TaskManager">
265
+ <task active="true" id="Default" summary="Default task">
266
+ <changelist id="92478032-adc2-4ebf-bd18-29b0175af59f" name="Default" comment="" />
267
+ <created>1459447159915</created>
268
+ <option name="number" value="Default" />
269
+ <updated>1459447159915</updated>
270
+ </task>
271
+ <servers />
272
+ </component>
273
+ <component name="ToolWindowManager">
274
+ <frame x="457" y="60" width="1502" height="1165" extended-state="0" />
275
+ <editor active="false" />
276
+ <layout>
277
+ <window_info id="Messages" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.3295129" sideWeight="0.5" order="-1" side_tool="false" content_ui="tabs" />
278
+ <window_info id="Terminal" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="-1" side_tool="false" content_ui="tabs" />
279
+ <window_info id="TODO" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="6" side_tool="false" content_ui="tabs" />
280
+ <window_info id="Find" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" weight="0.3295129" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
281
+ <window_info id="Database" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="-1" side_tool="false" content_ui="tabs" />
282
+ <window_info id="Structure" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.25" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
283
+ <window_info id="Application Servers" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="-1" side_tool="false" content_ui="tabs" />
284
+ <window_info id="Project" active="true" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" weight="0.25" sideWeight="0.5" order="0" side_tool="false" content_ui="combo" />
285
+ <window_info id="Favorites" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="-1" side_tool="true" content_ui="tabs" />
286
+ <window_info id="Event Log" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="-1" side_tool="true" content_ui="tabs" />
287
+ <window_info id="Version Control" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="-1" side_tool="false" content_ui="tabs" />
288
+ <window_info id="Cvs" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.25" sideWeight="0.5" order="4" side_tool="false" content_ui="tabs" />
289
+ <window_info id="Message" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
290
+ <window_info id="Ant Build" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.25" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
291
+ <window_info id="Commander" active="false" anchor="right" auto_hide="false" internal_type="SLIDING" type="SLIDING" visible="false" weight="0.4" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
292
+ <window_info id="Debug" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.4" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
293
+ <window_info id="Run" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" />
294
+ <window_info id="Inspection" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.4" sideWeight="0.5" order="5" side_tool="false" content_ui="tabs" />
295
+ <window_info id="Hierarchy" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.25" sideWeight="0.5" order="2" side_tool="false" content_ui="combo" />
296
+ </layout>
297
+ </component>
298
+ <component name="VcsContentAnnotationSettings">
299
+ <option name="myLimit" value="2678400000" />
300
+ </component>
301
+ <component name="XDebuggerManager">
302
+ <breakpoint-manager />
303
+ <watches-manager />
304
+ </component>
305
+ <component name="editorHistoryManager">
306
+ <entry file="file://$PROJECT_DIR$/Gemfile">
307
+ <provider selected="true" editor-type-id="text-editor">
308
+ <state vertical-scroll-proportion="0.0">
309
+ <caret line="4" column="0" selection-start-line="4" selection-start-column="0" selection-end-line="4" selection-end-column="0" />
310
+ <folding />
311
+ </state>
312
+ </provider>
313
+ </entry>
314
+ <entry file="file://$PROJECT_DIR$/Rakefile">
315
+ <provider selected="true" editor-type-id="text-editor">
316
+ <state vertical-scroll-proportion="0.0">
317
+ <caret line="3" column="32" selection-start-line="3" selection-start-column="32" selection-end-line="3" selection-end-column="32" />
318
+ <folding />
319
+ </state>
320
+ </provider>
321
+ </entry>
322
+ <entry file="file://$PROJECT_DIR$/webpush.gemspec">
323
+ <provider selected="true" editor-type-id="text-editor">
324
+ <state vertical-scroll-proportion="0.0">
325
+ <caret line="18" column="0" selection-start-line="18" selection-start-column="0" selection-end-line="18" selection-end-column="0" />
326
+ <folding />
327
+ </state>
328
+ </provider>
329
+ </entry>
330
+ <entry file="file://$PROJECT_DIR$/bin/setup">
331
+ <provider selected="true" editor-type-id="text-editor">
332
+ <state vertical-scroll-proportion="0.0">
333
+ <caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
334
+ <folding />
335
+ </state>
336
+ </provider>
337
+ </entry>
338
+ <entry file="file://$PROJECT_DIR$/lib/webpush/version.rb">
339
+ <provider selected="true" editor-type-id="text-editor">
340
+ <state vertical-scroll-proportion="0.06676558">
341
+ <caret line="3" column="0" selection-start-line="3" selection-start-column="0" selection-end-line="3" selection-end-column="0" />
342
+ <folding />
343
+ </state>
344
+ </provider>
345
+ </entry>
346
+ </component>
347
+ </project>
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.3.0
4
+ before_install: gem install bundler -v 1.11.2
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in webpush.gemspec
4
+ gemspec
@@ -0,0 +1,39 @@
1
+ # WebPush
2
+
3
+ This Gem will send the Web Push API. It supports the encryption necessary to payload.
4
+
5
+ Payload is supported by Chrome50+.
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'webpush'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install webpush
22
+
23
+ ## Usage
24
+
25
+ ```
26
+ message = {
27
+ hoge: "piyo"
28
+ }
29
+
30
+ Webpush.payload_send(message: JSON.generate(message),
31
+ endpoint: "https://android.googleapis.com/gcm/send/eah7hak....",
32
+ p256dh: "BO/aG9nYXNkZmFkc2ZmZHNmYWRzZmFl...",
33
+ auth: "aW1hcmthcmFpa3V6ZQ==",
34
+ api_key: "[GoogleDeveloper APIKEY]")
35
+ ```
36
+
37
+ ## Contributing
38
+
39
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/webpush.
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "webpush"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,125 @@
1
+ require 'webpush/version'
2
+ require 'openssl'
3
+ require 'base64'
4
+ require 'hkdf'
5
+ require 'net/http'
6
+ require 'json'
7
+
8
+ module Webpush
9
+
10
+ # It is temporary URL until supported by the GCM server.
11
+ GCM_URL = 'https://android.googleapis.com/gcm/send'
12
+ TEMP_GCM_URL = 'https://gcm-http.googleapis.com/gcm'
13
+
14
+ class << self
15
+ def payload_send(message:, endpoint:, p256dh:, auth:, api_key:)
16
+ endpoint = endpoint.gsub(GCM_URL, TEMP_GCM_URL)
17
+ p256dh = unescape_base64(p256dh)
18
+ auth = unescape_base64(auth)
19
+
20
+ payload = encrypt(message, p256dh, auth)
21
+ gcm_post(endpoint, payload, api_key)
22
+ end
23
+
24
+ private
25
+
26
+ def gcm_post(endpoint, payload, api_key)
27
+ begin
28
+ uri = URI.parse(endpoint)
29
+ http = Net::HTTP.new(uri.host, uri.port)
30
+ http.use_ssl = true
31
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
32
+ header = {
33
+ "Encryption" => "salt=#{Base64.urlsafe_encode64(payload[:salt]).delete('=')}",
34
+ "Crypto-Key" => "dh=#{Base64.urlsafe_encode64(payload[:server_public_key_bn]).delete('=')}",
35
+ "Authorization" => "key=#{api_key}"
36
+ }
37
+ req = Net::HTTP::Post.new(uri.request_uri, header)
38
+ req.body = payload[:ciphertext]
39
+ res = http.request(req)
40
+ return ("201" == res.code) ? true : false
41
+ rescue
42
+ return false
43
+ end
44
+ end
45
+
46
+ def encrypt(message, p256dh, auth)
47
+ group_name = "prime256v1"
48
+ salt = Random.new.bytes(16)
49
+
50
+ server = OpenSSL::PKey::EC.new(group_name)
51
+ server.generate_key
52
+ server_public_key_bn = server.public_key.to_bn
53
+
54
+ group = OpenSSL::PKey::EC::Group.new(group_name)
55
+ client_public_key_hex = Base64.decode64(p256dh).unpack("H*").first
56
+ client_public_key_bn = OpenSSL::BN.new(client_public_key_hex, 16)
57
+ client_public_key = OpenSSL::PKey::EC::Point.new(group, client_public_key_bn)
58
+
59
+ shared_secret = server.dh_compute_key(client_public_key)
60
+
61
+ clientAuthToken = Base64.decode64(auth)
62
+
63
+ prk = HKDF.new(shared_secret, :salt => clientAuthToken, :algorithm => 'SHA256', :info => "Content-Encoding: auth\0").next_bytes(32)
64
+
65
+ context = create_context(client_public_key_bn, server_public_key_bn)
66
+
67
+ content_encryption_key_info = create_info('aesgcm', context)
68
+ content_encryption_key = HKDF.new(prk, :salt => salt, :info => content_encryption_key_info).next_bytes(16)
69
+
70
+ nonce_info = create_info('nonce', context)
71
+ nonce = HKDF.new(prk, :salt => salt, :info => nonce_info).next_bytes(12)
72
+
73
+ ciphertext = encrypt_payload(message, content_encryption_key, nonce)
74
+
75
+ {
76
+ ciphertext: ciphertext,
77
+ salt: salt,
78
+ server_public_key_bn: convert16bit(server_public_key_bn)
79
+ }
80
+ end
81
+
82
+ def create_context(clientPublicKey, serverPublicKey)
83
+ c = convert16bit(clientPublicKey)
84
+ s = convert16bit(serverPublicKey)
85
+ context = "\0"
86
+ context += [c.bytesize].pack("n*")
87
+ context += c
88
+ context += [s.bytesize].pack("n*")
89
+ context += s
90
+ context
91
+ end
92
+
93
+ def encrypt_payload(plaintext, content_encryption_key, nonce)
94
+ cipher = OpenSSL::Cipher.new('aes-128-gcm')
95
+ cipher.encrypt
96
+ cipher.key = content_encryption_key
97
+ cipher.iv = nonce
98
+ padding = cipher.update("\0\0")
99
+ text = cipher.update(plaintext)
100
+
101
+ e_text = padding + text + cipher.final
102
+ e_tag = cipher.auth_tag
103
+
104
+ e_text + e_tag
105
+ end
106
+
107
+ def create_info(type, context)
108
+ info = "Content-Encoding: "
109
+ info += type
110
+ info += "\0"
111
+ info += "P-256"
112
+ info += context
113
+ info
114
+ end
115
+
116
+ def convert16bit(key)
117
+ [key.to_s(16)].pack("H*")
118
+ end
119
+
120
+ def unescape_base64(base64)
121
+ base64.gsub(/_|\-/, "_" => "/", "-" => "+")
122
+ end
123
+ end
124
+
125
+ end
@@ -0,0 +1,3 @@
1
+ module Webpush
2
+ VERSION = "0.1.1"
3
+ end
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'webpush/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "webpush"
8
+ spec.version = Webpush::VERSION
9
+ spec.authors = ["zaru@sakuraba"]
10
+ spec.email = ["zarutofu@gmail.com"]
11
+
12
+ spec.summary = %q{Encryption Utilities for Web Push payload. }
13
+ spec.homepage = "https://github.com/zaru/webpush"
14
+
15
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
16
+ spec.bindir = "exe"
17
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
18
+ spec.require_paths = ["lib"]
19
+
20
+ spec.add_development_dependency "bundler", "~> 1.11"
21
+ spec.add_development_dependency "rake", "~> 10.0"
22
+ spec.add_development_dependency "rspec", "~> 3.0"
23
+ spec.add_development_dependency "hkdf", "~> 0.2"
24
+ end
metadata ADDED
@@ -0,0 +1,117 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: webpush
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - zaru@sakuraba
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2016-03-31 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.11'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.11'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: hkdf
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '0.2'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '0.2'
69
+ description:
70
+ email:
71
+ - zarutofu@gmail.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - ".gitignore"
77
+ - ".idea/.name"
78
+ - ".idea/.rakeTasks"
79
+ - ".idea/misc.xml"
80
+ - ".idea/modules.xml"
81
+ - ".idea/vcs.xml"
82
+ - ".idea/webpush.iml"
83
+ - ".idea/workspace.xml"
84
+ - ".rspec"
85
+ - ".travis.yml"
86
+ - Gemfile
87
+ - README.md
88
+ - Rakefile
89
+ - bin/console
90
+ - bin/setup
91
+ - lib/webpush.rb
92
+ - lib/webpush/version.rb
93
+ - webpush.gemspec
94
+ homepage: https://github.com/zaru/webpush
95
+ licenses: []
96
+ metadata: {}
97
+ post_install_message:
98
+ rdoc_options: []
99
+ require_paths:
100
+ - lib
101
+ required_ruby_version: !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - ">="
104
+ - !ruby/object:Gem::Version
105
+ version: '0'
106
+ required_rubygems_version: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ requirements: []
112
+ rubyforge_project:
113
+ rubygems_version: 2.5.1
114
+ signing_key:
115
+ specification_version: 4
116
+ summary: Encryption Utilities for Web Push payload.
117
+ test_files: []